Pour un sous-arbre de recherche binaire maximal trouver arbre binaire donné

voix
13

Pour un arbre binaire donné, trouver le plus grand sous-arbre qui est aussi l'arbre de recherche binaire?

Exemple:

Contribution:

                   10
               /         \
             50           150
            /  \         /   \
          25    75     200    20
         / \   / \    /  \    / \
        15 35 65 30  120 135 155 250 

Sortie:

                   50
                  /   \
                 25   75
                / \   /
               15 35  65
Créé 02/07/2010 à 06:15
source utilisateur
Dans d'autres langues...                            


7 réponses

voix
0

Un arbre binaire de recherche vous donnera un résultat Sorted si vous faites dans l'ordre Traversal. Alors, faites un en ordre traversal pour l'ensemble de l'arbre binaire. La séquence la plus longue triée est votre plus grand arbre de recherche binaire sous.

  • Faites un parcours infixe d'éléments (GAUCHE VISITE, RACINE VISITE, DROIT VISITE)
  • Ce faisant, obtenir les données de noeud, comparer si les données de nœud précédent est moindre que les données suivantes. Si oui, par incrémentation du compteur 1. Conserver le noeud de départ.
  • Lorsque la comparaison échoue, stocker le noeud d'extrémité et réinitialiser le compteur à 0
  • Conservez ces informations (compteur, début, fin) noeud dans une structure de tableau pour trouver plus tard qui est d'avoir la valeur maximale et qui vous donnera le plus long sous-arbre de recherche binaire
Créé 02/07/2010 à 06:26
source utilisateur

voix
2

Question interessante!

Ma première tentative était moronically mal!

Voici une autre tentative (corriger, espérons cette fois-ci).

Je suppose que l'arbre est connecté.

Supposons que pour chaque nœud n de l'arbre, vous avez eu un ensemble de descendants de n, S n avec la propriété

  • Pour chaque membre x de S n , le chemin unique de n à x est un arbre de recherche binaire (il est seulement un chemin, mais vous pouvez toujours considérer un arbre).

  • Pour chaque descendant y de x, de telle sorte que la voie de n à y est un BST, y est dans S n .

L'ensemble des noeuds S n , vous donne la plus grande BST à n enraciné.

On peut construire S n pour chaque noeud en effectuant une recherche en profondeur d' abord sur l'arbre, et en transmettant les informations de chemin (le chemin de la racine au noeud de courant) et la mise à jour des ensembles de noeuds dans le chemin de retour en arrière le long du trajet.

Quand on visite un nœud, nous marchons le chemin, et vérifier si la propriété BST est satisfaite pour ce segment du chemin a marché jusqu'à présent. Si oui, nous ajoutons le nœud courant à l'ensemble correspondant du nœud du chemin que nous y sommes allés à. Nous cessons de marcher sur le chemin du moment où la propriété BST est violée. Vérifier si le segment de chemin on a marché à ce jour est un BST peut être fait en O (1) fois, pour une O (PATH_LENGTH) Temps de temps de traitement total, pour chaque noeud.

A la fin, chaque noeud aura son correspondant S n peuplé. Nous pouvons marcher l'arbre maintenant et choisissez le nœud avec la plus grande valeur de S n .

Le temps nécessaire pour cela est la somme des profondeurs des nœuds (dans le pire des cas), et qui est O (nlogn) dans le cas moyen (voir la section 5.2.4 de http://www.toves.org/books/ données / CH05-arbres / index.html ), mais O (n ^ 2) dans le pire des cas.

Peut-être une façon de mettre à jour les plus habiles jeux garantira une réduction du pire moment de cas.

Le pseudo-code pourrait être quelque chose comme:

static Tree void LargestBST(Tree t)
{
    LargestBST(t, new List<Pair>());
    // Walk the tree and return the largest subtree with max |S_n|.
}

static Tree LargestBST(Tree t, List<Pair> path)
{
    if (t == null) return;

    t.Set.Add(t.Value);

    int value = t.Value;
    int maxVal = value;
    int minVal = value;

    foreach (Pair p in path)
    {
        if (p.isRight)
        {
            if (minVal < p.node.Value)
            {
                break;
            }
        }

        if (!p.isRight)
        {
            if (maxVal > p.node.Value)
            {
                break;
            }
        }

        p.node.Set.Add(t.Value);

        if (p.node.Value <= minVal)
        {
            minVal = p.node.Value;
        }

        if (p.node.Value >= maxVal)
        {
            maxVal = p.node.Value;
        }
    }

    Pair pl = new Pair();
    pl.node = t;
    pl.isRight = false;

    path.Insert(0, pl);
    LargestBST(t.Left, path);

    path.RemoveAt(0);

    Pair pr = new Pair();
    pr.node = t;
    pr.isRight = true;

    path.Insert(0, pr);

    LargestBST(t.Right, path);

    path.RemoveAt(0);

}
Créé 02/07/2010 à 14:13
source utilisateur

voix
0
GetLargestSortedBinarySubtree(thisNode, ref OverallBestTree)
    if thisNode == null
        Return null
    LeftLargest = GetLargestSortedBinarySubtree(thisNode.LeftNode, ref OverallBestTree)
    RightLargest = GetLargestSortedBinarySubtree(thisNode.RightNode, ref OverallBestTree)
    if LeftLargest.Max < thisNode.Value & RightLargest.Min > thisNode.Value
        currentBestTree = new BinaryTree(LeftLargest, thisNode.Value, RightLargest)
    else if LeftLargest.Max < thisNode.Value
        currentBestTree = new BinaryTree(LeftLargest, thisNode.Value, null)
    else if RightLargest.Min > thisNode.Value
        currentBestTree = new BinaryTree(null, thisNode.Value, RightLargest)
    else
        currentBestTree = new BinaryTree(null, thisNode.Value, null)
    if (currentBestTree.Size > OverallBestTree.Size)
        OverallBestTree = currentBestTree
    return currentBestTree

Comme BlueRaja a souligné, cet algorithme est incorrect.

Il devrait vraiment être appelé GetLargestSortedBinarySubtreeThatCanBeRecursivelyConstructedFromMaximalSortedSubtrees.

Créé 02/07/2010 à 19:46
source utilisateur

voix
3

L'algorithme précédent (voir les révisions) était O(n^2)- nous pouvons généraliser à O(n log n)en remarquant les faits que:

  1. Si b est la racine de la plus grande et BST b.left.value < b.value, puis b.leftest également dans le BST (même pour b.right.value ≥ b.value)
  2. Si b est la racine de la plus grande BST et est également dans le BST, alors chaque nœud entre a et b est dans la BST.

Donc , si c est entre a et b, et c est pas dans la BST enracinée par b, ni est un ( en raison de (2)) . L' utilisation de ce fait, on peut facilement déterminer si un nœud est dans le BST enraciné par un ancêtre donné. Nous allons le faire en passant un nœud dans notre fonction , ainsi qu'une liste de ses ancêtres, et min / maxValues associé que l'enfant nœud actuel devrait satisfaire si bien que l' ancêtre était la racine du plus grand BST (nous » ll appeler cette liste ancestorList). Nous allons stocker la collection de racines potentiellesoverallRootsList

Définissons une structure appelée potentialRoot comme suit:

Chaque potentialRoot contient les valeurs suivantes:
* nœud : Le nœud que nous envisageons pour la racine du BST
* minValue maxvalue : la gamme un autre nœud doit être comprise entre faire partie du BST enracinée par noeud (différent pour chaque noeud)
* sous - noeuds : Une liste du reste des noeuds dans la plus grande BST enracinée par le noeud

Le pseudo - code ressemble à ceci (notez que toutes les listes mentionnées sont des listes de potentialRoots) :

FindLargestBST(node, ancestorList):
    leftList, rightList = empty lists
    for each potentialRoot in ancestorList:
        if potentialRoot.minValue < node.Value ≤ potentialRoot.maxValue:
            add node to potentialRoot.subNodes (due to (1.))
            (note that the following copies contain references, not copies, of subNodes)
            add copy of potentialRoot to leftList, setting maxValue = node.Value
            add copy of potentialRoot to rightList, setting minValue = node.Value

    add the potentialRoot (node, -∞, +∞) to leftList, rightList, and overallRootsList
    FindLargestBST(node.left, leftList)
    FindLargestBST(node.right, rightList)

A la fin overallRootsListsera une liste de npotentialRoots, chacun avec une liste des sous - noeuds. Celui qui a la plus grande liste de sous - noeuds est votre BST.

Comme il y a <valeurs treeHeight dans ancestorList, puis ( en supposant l'arbre est équilibré), l'algorithme fonctionne enO(n log n)

Créé 02/07/2010 à 20:21
source utilisateur

voix
0
root(Tree L A R) = A

MaxBST(NULL) = (true, 0, NULL)
MaxBST(Tree L A R as T) = 
  let
    # Look at both children
    (L_is_BST, L_size, L_sub) = MaxBST(L)
    (R_is_BST, R_size, R_sub) = MaxBST(R)
  in
  # If they're both good, then this node might be good too
  if L_is_BST and R_is_BST and (L == NULL or root(L) < A) and (R == NULL or A < root(R))
  then (true, 1 + L_size + R_size, T)
  else
       # This node is no good, so give back the best our children had to offer
       (false, max(L_size, R_size), if L_size > R_size then L_sub else R_sub)

On dirait à chaque noeud d'arbre exactement une fois, si court dans O (N).

Edit: Crud, cela ne considère pas qu'il peut laisser quelques parties d'un sous-arbre. Quand je lis sous-arbre, je suppose « l'arbre entier ancré à un noeud ». Je reviendrai peut-être à corriger plus tard.

Créé 03/07/2010 à 01:15
source utilisateur

voix
4

Cette réponse contenait précédemment un O (n log n) algorithme basé sur les arbres lien / coupe. Voici un simple O (n) solution.

Le noyau est une procédure qui accepte un noeud, le BSST unique maximum ancré à son enfant à gauche, le BSST unique maximum ancré à son enfant à droite, et les pointeurs vers les plus à gauche et à droite la plupart des éléments de ces BSSTs. Il détruit ses entrées (évitables avec des structures de données persistantes) et construit le BSST unique maximum ancré au niveau du noeud donné, ainsi que ses éléments minimum et maximum. Tous les nœuds BSST sont annotés avec le nombre de descendants. Comme précédemment, cette procédure est appelée à plusieurs reprises d'un traversal post-commande. Pour récupérer le sous-arbre, rappelez-vous la racine du plus grand BSST; la reconstruction nécessite un simple traversal.

Je vais traiter la seule BSST gauche; la droite est symétrique. Si la racine du BSST gauche est supérieure à la nouvelle racine, puis on retire l'ensemble du sous-arbre, et la nouvelle racine est maintenant la plus à gauche. Dans le cas contraire, l'ancienne gauche nœud le plus est encore plus à gauche. A partir de la droite la plus nœud du BSST gauche et déplacer vers le haut, trouver le premier noeud qui est inférieur ou égal à la racine. Son droit de l' enfant doit être retiré; noter maintenant qu'en raison de la propriété BST, pas d' autres nœuds doivent aller! Passez à la racine du BSST gauche, mise à jour des comptes pour refléter la suppression.

La raison pour cela est O (n) est que, en dépit de la boucle, chaque bord de l'arborescence d'origine est essentiellement traversée une seule fois.


EDIT: collectivement, les chemins parcourus sont les maximales parcours en ligne droite dans un BST, à l'exception de la colonne vertébrale gauche et la colonne vertébrale droite. Par exemple, sur l'entrée

              H
             / \
            /   \
           /     \
          /       \
         /         \
        /           \
       /             \
      D               L
     / \             / \
    /   \           /   \
   /     \         /     \
  B       F       J       N
 / \     / \     / \     / \
A   C   E   G   I   K   M   O

voici les appels récursifs sur lequel chaque bord est traversée:

              H
             / \
            /   \
           /     \
          /       \
         /         \
        /           \
       /             \
      D               L
     / h             h \
    /   h           h   \
   /     h         h     \
  B       F       J       N
 / d     d h     h l     l \
A   C   E   G   I   K   M   O
Créé 03/07/2010 à 17:46
source utilisateur

voix
1

RECHERCHE PLUS GRANDE TREE BINARY DANS UN ARBRE BINARY:

Il y a deux façons dont nous pouvons aborder ce problème,

i) La plus grande BST n'induit (à partir d'un noeud, tous ses enfants ne sont pas soumises à la condition de BST)

ii) la plus grande BST induites (d'un nœud, tous ses enfants satisfaire à la condition de BST)

Nous allons discuter de la plus grande BST (pas Induced) ici. Nous allons approche FOLLOW ascendante (Publier traversal) pour résoudre ce problème.

a) atteindre le noeud feuille

b) un noeud d'arborescence (à partir de la feuille) retourne un objet TreeNodeHelper qui a les champs suivants en elle.

public static class TreeNodeHelper {
        TreeNode node;
        int nodes;
        Integer maxValue;
        Integer minValue;
        boolean isBST;


        public TreeNodeHelper() {}

        public TreeNodeHelper(TreeNode node, int nodes, Integer maxValue, Integer minValue, boolean isBST) {
            this.node = node;
            this.nodes = nodes;
            this.maxValue = maxValue;
            this.minValue = minValue;
            this.isBST = isBST;
        }      
    }

c) Dans un premier temps depuis le noeud de feuille, les nœuds = 1, isBST = true, minValue = maxValue = node.data. Et plus loin, les noeuds COUNT seront augmentés si elle satisfait à la condition de BST.

d) Avec l'aide de cela, nous allons vérifier l'état de BST avec noeud courant. Et nous allons répéter la même jusqu'à la racine.

e) De chaque nœud deux objets seront renvoyés. une dernière pour la BST et un autre maximum pour les noeuds de courant BST satisfaisants. Donc, à partir de chaque nœud (au-dessus des feuilles) (2 + 2) = 4 (2 pour sous-arbre gauche et 2 pour sous-arbre droit) objets seront comparés et deux seront retournés.

f) L'objet de noeud de la racine finale maximale sera le plus grand BST

PROBLÈME:

Il y a un problème dans cette approche. En suivant cette approche, si un sous-arbre ne satisfait pas la condition de BST avec le nœud actuel, on ne peut passer sous silence le sous-arbre (même il a moins de nombre de nœuds). Par exemple

 55
  \
   75
  /  \
 27  89
    /  \
   26  95
      /  \
     23  105
         /  \
        20  110

A partir des nœuds feuilles (20110) les objets seront testés avec le noeud (105), il satisfait à la condition. Mais quand il atteint le noeud (95), le nœud feuille (20) ne satisfait pas à la condition de BST. Étant donné que cette solution est BST (pas induite) il ne faut pas ignorer le noeud (105) et le noeud (110) qui satisfait la condition. Donc, à partir du noeud (95), nous devons revenir en arrière tester à nouveau l'état de BST et attraper ces noeuds (105, 110).

Le code complet pour cette mise en œuvre est disponible dans ce lien

https://github.com/dineshappavoo/Implementation/tree/master/LARGEST_BST_IN_BT_NOT_INDUCED_VER1.0

Créé 27/03/2014 à 00:48
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more