Για ένα δεδομένο δυαδικό δέντρο βρείτε τη μέγιστη δυαδική αναζήτηση υπο-δέντρο

ψήφοι
13

Για ένα δεδομένο δυαδικό δέντρο, βρείτε τη μεγαλύτερη υποδέντρο που είναι επίσης δυαδικό δένδρο αναζήτησης;

Παράδειγμα:

Εισαγωγή:

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

Παραγωγή:

                   50
                  /   \
                 25   75
                / \   /
               15 35  65
Δημοσιεύθηκε 02/07/2010 στις 06:15
πηγή χρήστη
Σε άλλες γλώσσες...                            


7 απαντήσεις

ψήφοι
0

Ένα δυαδικό δένδρο αναζήτησης θα σας δώσει μια ταξινομημένη αποτέλεσμα αν κάνετε μια εν σειρά διέλευσης. Έτσι, κάνουμε μια διάσχιση στη σειρά για ολόκληρη τη δυαδικό δέντρο. Η μεγαλύτερη ταξινομημένη ακολουθία είναι η μεγαλύτερη δυαδική αναζήτηση υπο το δέντρο σας.

  • Κάνετε μια inorder διάσχιση των στοιχείων (ΕΠΙΣΚΕΨΗ ΑΡΙΣΤΕΡΑ, ΕΠΙΣΚΕΨΗ ΡΙΖΑ, VISIT ΔΕΞΙΑ)
  • Πράττοντας αυτό, να πάρει τα δεδομένα κόμβου, συγκρίνετε το αν η προηγούμενη δεδομένων κόμβου είναι μικρότερο από ό, τι τα επόμενα δεδομένα. Αν ναι, αυξάνει μετρητή κατά 1. Αποθηκεύστε το κόμβο εκκίνησης.
  • Όταν η σύγκριση αποτύχει, αποθηκεύστε το τέλος του κόμβου και να επαναφέρετε σε αντίθεση με 0
  • Φυλάξτε αυτές τις πληροφορίες (σε αντίθεση, αρχή, τέλος) κόμβο σε μια δομή πίνακα για αργότερα βρείτε ποια έχει την μέγιστη τιμή και ότι θα σας δώσει τη μεγαλύτερη δυαδική αναζήτηση υπο δέντρο
Απαντήθηκε 02/07/2010 στις 06:26
πηγή χρήστη

ψήφοι
2

Ενδιαφέρουσα ερώτηση!

νωρίτερα Η προσπάθειά μου ήταν moronically λάθος!

Εδώ είναι μια άλλη προσπάθεια (ελπίζω να διορθώσετε αυτή τη φορά).

Υποθέτω το δέντρο είναι συνδεδεμένο.

Ας υποθέσουμε ότι για κάθε κόμβο n του δέντρου, που είχε μια σειρά από απογόνους των n, S n με την ιδιότητα που

  • Για κάθε x μέλος της S n , το μοναδικό μονοπάτι από n σε x είναι ένα δυαδικό Αναζήτηση δέντρο (δεν είναι μόνο ένα μονοπάτι, αλλά μπορείτε ακόμα να το θεωρούν ένα δέντρο).

  • Για κάθε απόγονος y του x, έτσι ώστε η διαδρομή από η προς γ είναι ένας BST, το γ είναι σε S n .

Το σύνολο των κόμβων S n , σας δίνει τη μεγαλύτερη BST ριζωμένη στο n.

Μπορούμε να κατασκευάσουμε S n για κάθε κόμβο κάνοντας μια αναζήτηση κατά βάθος στο δέντρο, και περνώντας στις πληροφορίες διαδρομή (μονοπάτι από τη ρίζα μέχρι τον τρέχοντα κόμβο) και την ενημέρωση των συνόλων των κόμβων στη διαδρομή από αναγκασθεί κατά μήκος της διαδρομής.

Όταν επισκέπτεστε ένα κόμβο, περπατάμε το μονοπάτι, και να ελέγξετε εάν το ακίνητο BST είναι ικανοποιημένη γι 'αυτό το τμήμα της διαδρομής περπάτησε μέχρι τώρα. Αν ναι, προσθέτουμε το τρέχον κόμβο με την αντίστοιχη ομάδα του κόμβου της διαδρομής που μόλις περπάτησε στο. Θα σταματήσουν τα πόδια το μονοπάτι τη στιγμή που η ιδιότητα BST παραβιάζεται. Έλεγχος εάν το τμήμα διαδρομής περπατήσαμε μέχρι στιγμής είναι ένα BST μπορεί να γίνει σε O (1) ώρα, για μια O (PATH_LENGTH) χρόνος χρόνος συνολικής επεξεργασίας, για κάθε κόμβο.

Στο τέλος, κάθε κόμβος θα έχει αντίστοιχη S του n κατοικείται. Μπορούμε να περπατήσει το δέντρο τώρα και να πάρει τον κόμβο με τη μεγαλύτερη τιμή της S n .

Ο χρόνος που απαιτείται για το σκοπό αυτό είναι το άθροισμα των βάθη των κόμβων (στη χειρότερη περίπτωση), και ότι είναι O (nlogn) στην μέση περίπτωση (βλέπε Ενότητα 5.2.4 της http://www.toves.org/books/ δεδομένων / Ch05-δένδρα / index.html ), αλλά O (n ^ 2) στη χειρότερη περίπτωση.

Ίσως ένας έξυπνος τρόπος για να ενημερώσετε τα σετ θα εγγυηθεί μια μείωση στη χειρότερη στιγμή υπόθεση.

Ο ψευδο-κώδικας θα μπορούσε να είναι κάτι σαν:

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);

}
Απαντήθηκε 02/07/2010 στις 14:13
πηγή χρήστη

ψήφοι
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

Όπως BlueRaja τόνισε, αυτός ο αλγόριθμος δεν είναι σωστή.

Θα πρέπει πραγματικά να ονομάζεται GetLargestSortedBinarySubtreeThatCanBeRecursivelyConstructedFromMaximalSortedSubtrees.

Απαντήθηκε 02/07/2010 στις 19:46
πηγή χρήστη

ψήφοι
3

Το προηγούμενο αλγόριθμο (βλέπε αναθεωρήσεις) ήταν O(n^2)- μπορούμε να το γενικεύσουμε να O(n log n)παρατηρώντας τα γεγονότα ότι:

  1. Αν β είναι η ρίζα του μεγαλύτερου BST και b.left.value < b.value, στη συνέχεια, b.leftείναι επίσης προς το BST (ίδιο για b.right.value ≥ b.value)
  2. Αν β είναι η ρίζα του μεγαλύτερου BST και το α είναι επίσης στη BST, τότε κάθε κόμβος μεταξύ a και b είναι στο BST.

Έτσι, αν c είναι μεταξύ a και b, και c δεν είναι στη BST τις ρίζες του β, δεν είναι (λόγω της (2)) . Χρησιμοποιώντας αυτό το γεγονός, μπορούμε εύκολα να προσδιορίσετε αν ένας κόμβος είναι στη BST τις ρίζες της από οποιαδήποτε πρόγονο. Θα το κάνουμε αυτό με το πέρασμα ενός κόμβου στη λειτουργία μας, μαζί με μια λίστα των προγόνων του, και η σχετική λεπτά / maxValues ότι η σημερινή παιδί-κόμβου θα πρέπει να πληρούν εάν πράγματι ότι πρόγονος ήταν η ρίζα του μεγαλύτερου BST (εμείς» ll να καλέσετε αυτόν τον κατάλογο ancestorList). Θα αποθηκεύσει ολόκληρη τη συλλογή του δυναμικού ρίζες στοoverallRootsList

Ας ορίσουμε μια δομή που ονομάζεται potentialRoot ως εξής:

Κάθε potentialRoot περιέχει τις ακόλουθες τιμές:
* κόμβο : Ο κόμβος που εξετάζουμε για τη ρίζα του BST
* MINVALUE και MAXVALUE : το εύρος άλλος κόμβος πρέπει να κυμαίνεται μεταξύ να είναι μέρος του BST τις ρίζες από τον κόμβο (διαφορετική για κάθε κόμβο)
* subnodes : Μια λίστα με τα υπόλοιπα των κόμβων στο μεγαλύτερο BST τις ρίζες της από κόμβο

Ο κώδικας ψευδο μοιάζει με αυτό (να σημειωθεί ότι όλοι οι κατάλογοι που αναφέρονται είναι λίστες 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)

Στο τέλος overallRootsListθα είναι μια λίστα των npotentialRoots, το καθένα με μια λίστα των subnodes. Το ένα με τη μεγαλύτερη λίστα subnodes είναι BST σας.

Δεδομένου ότι υπάρχουν <treeHeight τιμές στο ancestorList, τότε (υποθέτοντας ότι το δέντρο είναι ισορροπημένη), ο αλγόριθμος τρέχει σεO(n log n)

Απαντήθηκε 02/07/2010 στις 20:21
πηγή χρήστη

ψήφοι
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)

Φαίνεται σε κάθε κόμβο του δένδρου ακριβώς μια φορά, έτσι τρέχει σε O (N).

Επεξεργασία: ακατέργαστο, αυτό δεν θεωρεί ότι μπορεί να αφήσει έξω κάποια μέρη του υποδέντρο. Όταν διάβασα δευτερεύον δέντρο, υπέθεσα «ολόκληρο το δέντρο ριζωμένο σε κάποιο κόμβο». Θα μπορεί να έρθει πίσω για να διορθώσετε αυτό αργότερα.

Απαντήθηκε 03/07/2010 στις 01:15
πηγή χρήστη

ψήφοι
4

Αυτή η απάντηση περιείχε προηγουμένως ο O (n log n) αλγόριθμο βασισμένο σε σύνδεση / κοπή δέντρων. Εδώ είναι μια απλούστερη O (n) διάλυμα.

Ο πυρήνας είναι μια διαδικασία που δέχεται έναν κόμβο, η μοναδική μέγιστη BSST ριζωμένη στα αριστερά του παιδιού της, η μοναδική μέγιστη BSST τις ρίζες της σε δικαίωμα του παιδιού της, και δείκτες προς τα αριστερά περισσότερο και δεξιά τα περισσότερα στοιχεία από αυτά τα BSSTs. Καταστρέφει εισόδους του (που μπορούν να αποφευχθούν με επίμονη δομές δεδομένων) και κατασκευάζει το μοναδικό μέγιστο BSST ριζωμένα στο δοσμένο κόμβο, μαζί με την ελάχιστη και τη μέγιστη στοιχεία. Όλοι οι κόμβοι BSST σχολιασμένη με τον αριθμό των απογόνων. Όπως και πριν, αυτή η διαδικασία ονομάζεται κατ 'επανάληψη από την διάσχιση μετά την παραγγελία. Για να ανακτήσετε το υπο-δέντρο, θυμηθείτε τη ρίζα του μεγαλύτερου BSST? ανακατασκευή απαιτεί μόνο ένα απλό διάσχισης.

Θα θεωρήσουν ότι το αριστερό BSST μόνο? το δικαίωμα είναι συμμετρική. Αν η ρίζα του αριστερού BSST είναι μεγαλύτερη από την νέα ρίζα, τότε το σύνολο υπο-δέντρο έχει αφαιρεθεί, και η νέα ρίζα είναι τώρα πιο αριστερά. Σε αντίθετη περίπτωση, η παλιά αριστερά πιο κόμβος εξακολουθεί αριστερά περισσότερο. Ξεκινώντας από το δεξί πιο κόμβο του αριστερού BSST και κινείται προς τα πάνω, βρείτε το πρώτο κόμβο που είναι μικρότερη ή ίση με τη ρίζα. Το δικαίωμα του παιδιού του πρέπει να αφαιρεθεί? Σημειώστε τώρα ότι λόγω της ιδιοκτησίας BST, δεν υπάρχουν άλλοι κόμβοι πρέπει να πάτε! Προχωρήστε στη ρίζα του αριστερού BSST, την ενημέρωση των μετρήσεων ώστε να αντικατοπτρίζει τη διαγραφή.

Ο λόγος για αυτό είναι O (n) είναι ότι παρά του βρόχου, κάθε ακμή στην αρχική δέντρο είναι στην ουσία διασχίζεται μόνο μία φορά.


EDIT: συλλογικά, τα μονοπάτια διέσχιζε είναι η μέγιστη μονοπάτια ευθεία γραμμή σε ένα BST, εκτός από την αριστερά της σπονδυλικής στήλης και το δικαίωμα της σπονδυλικής στήλης. Για παράδειγμα, στην είσοδο

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

Εδώ είναι οι αναδρομικές κλήσεις στις οποίες διασχίζει κάθε άκρη:

              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
Απαντήθηκε 03/07/2010 στις 17:46
πηγή χρήστη

ψήφοι
1

ΜΕΓΑΛΥΤΕΡΗ δυαδική αναζήτηση δέντρο σε ένα δυαδικό δένδρο:

Υπάρχουν δύο τρόποι που μπορούμε να προσεγγίσουμε αυτό το πρόβλημα,

i) Ο μεγαλύτερος BST δεν προκαλείται (Από έναν κόμβο, όλα τα παιδιά της, δεν χρειάζεται να πληρούν την προϋπόθεση BST)

ii) Μεγαλύτερη BST που προκαλείται (Από έναν κόμβο, όλα τα παιδιά της θα πληροί την προϋπόθεση BST)

Θα συζητήσουμε για το μεγαλύτερο BST (που δεν προκαλείται) εδώ. Θα ακολουθήσουμε κάτω προς τα πάνω προσέγγιση (Δημοσίευση διάσχιση σειρά) για την επίλυση αυτού.

α) Reach τον κόμβο φύλλο

β) Ένα κόμβο του δένδρου (από το φύλλο) θα επιστρέψει ένα αντικείμενο TreeNodeHelper η οποία έχει τα ακόλουθα πεδία σε αυτό.

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;
        }      
    }

γ) Αρχικά από τον κόμβο φύλλο, κόμβους = 1, isBST = true, MINVALUE = MAXVALUE = node.data. Και επιπλέον, οι κόμβοι μετράνε θα αυξηθεί εάν πληροί την προϋπόθεση BST.

δ) Με τη βοήθεια αυτού, θα ελέγξουμε την κατάσταση BST με τρέχοντα κόμβο. Και θα επαναλάβουμε το ίδιο μέχρι ρίζας.

ε) Από κάθε κόμβο θα επιστραφούν δύο αντικείμενα. ένα για τελευταία μέγιστη BST και ένα άλλο για την τρέχουσα BST ικανοποιητική κόμβους. Έτσι, από κάθε κόμβο (ανωτέρω φύλλο) (2 + 2) = 4 (2 για το αριστερό υποδένδρο και 2 για το δικαίωμα υπο δέντρο) αντικείμενα θα συγκριθούν και δύο θα επιστραφούν.

στ) Η τελική μέγιστη αντικείμενο κόμβο από ρίζα θα είναι η μεγαλύτερη BST

ΠΡΟΒΛΗΜΑ:

Υπάρχει ένα πρόβλημα με αυτήν την προσέγγιση. Αν και μετά από αυτή την προσέγγιση, εάν ένα υποδένδρο δεν πληροί την προϋπόθεση BST με τον τρέχοντα κόμβο, δεν μπορούμε απλά να αγνοήσουμε το υποδένδρο (ακόμα και να έχει μικρότερο αριθμό κόμβων). Για παράδειγμα

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

Από τους κόμβους φύλλων (20110) τα αντικείμενα θα δοκιμαστούν με τον κόμβο (105), αυτό ικανοποιεί τη συνθήκη. Αλλά όταν φτάσει κόμβου (95) ο κόμβος φύλλο (20) δεν πληροί την προϋπόθεση BST. Δεδομένου ότι αυτή η λύση είναι για BST (δεν προκαλείται) δεν πρέπει να αγνοούμε κόμβο (105) και τον κόμβο (110), η οποία ικανοποιεί τη συνθήκη. Έτσι, από τον κόμβο (95) θα πρέπει να κάνουν πίσω και πάλι τον έλεγχο κατάστασης BST και να πιάσει αυτούς τους κόμβους (105, 110).

Η πλήρης κωδικός για την εφαρμογή αυτή είναι διαθέσιμη σε αυτό το σύνδεσμο

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

Απαντήθηκε 27/03/2014 στις 00:48
πηγή χρήστη

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