Στην Παραγγελία Διάδοχος σε δυαδική αναζήτηση Δέντρο

ψήφοι
20

Δεδομένης ένας κόμβος σε ένα BST, πώς μπορεί κανείς να βρει την επόμενη υψηλότερη κλειδί;

Δημοσιεύθηκε 29/03/2011 στις 12:25
πηγή χρήστη
Σε άλλες γλώσσες...                            


16 απαντήσεις

ψήφοι
2

Αναχώρηση εδώ: Inorder Διάδοχος σε μια δυαδική αναζήτηση Δέντρο

Σε Binary Tree, Inorder διάδοχος ενός κόμβου είναι ο επόμενος κόμβος Inorder διάσχιση του Binary Tree. Inorder Διάδοχος είναι NULL για το τελευταίο κόμβο στο Inoorder διάσχισης. Σε Binary Search Tree, Inorder Διάδοχος του κόμβου εισόδου μπορεί επίσης να οριστεί ως τον κόμβο με το μικρότερο κλειδί μεγαλύτερη από το κλειδί του κόμβου εισόδου.

Απαντήθηκε 29/03/2011 στις 12:28
πηγή χρήστη

ψήφοι
64

Ο γενικός τρόπος εξαρτάται από το αν έχετε ένα γονέα σύνδεση σε κόμβους ή όχι.

Αν αποθηκεύετε το μητρικό σύνδεσμο

Στη συνέχεια, μπορείτε να επιλέξετε:

  1. Το αριστερό παιδί του δικαιώματος του παιδιού, εάν το τρέχον κόμβος σας έχει δικαίωμα των παιδιών. Εάν το δικαίωμα του παιδιού δεν έχει αριστερό παιδί, το δικαίωμα του παιδιού είναι inorder διάδοχό σας.
  2. Πλοηγηθείτε μέχρι τους κόμβους πρόγονο γονέα, και όταν βρείτε ένα γονέα με το αριστερό παιδί είναι ο κόμβος είστε σήμερα στο, η μητρική είναι η inorder διάδοχος του αρχικού κόμβου σας.

Εάν έχετε το δικαίωμα του παιδιού, κάνει αυτή την προσέγγιση (περίπτωση 1 παραπάνω):

inorder-όταν-δεξιά-παιδιού

Εάν δεν έχετε το δικαίωμα των παιδιών, κάνει αυτή την προσέγγιση (περίπτωση 2 πιο πάνω):

inorder-όταν-χωρίς-δεξιά-παιδιού

Αν δεν αποθηκεύσετε το μητρικό σύνδεσμο

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

Απαντήθηκε 29/03/2011 στις 12:47
πηγή χρήστη

ψήφοι
2

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

public class Node<T extends Comparable<T>> {

private T data;
private Node<T> left;
private Node<T> right;

public Node(T data, Node<T> left, Node<T> right) {
    this.data = data;
    this.left = left;
    this.right = right;
}

/*
 * Returns the left-most node of the current node. If there is no left child, the current node is the left-most.
 */
private Node<T> getLeftMost() {
    Node<T> curr = this;
    while(curr.left != null) curr = curr.left;
    return curr;
}

/*
 * Returns the right-most node of the current node. If there is no right child, the current node is the right-most.
 */
private Node<T> getRightMost() {
    Node<T> curr = this;
    while(curr.right != null) curr = curr.right;
    return curr;
}

/**
 * Returns the in-order successor of the specified key.
 * @param key The key.
 * @return
 */
public T getSuccessor(T key) {
    Node<T> curr = this;
    T successor = null;
    while(curr != null) {
        // If this.data < key, search to the right.
        if(curr.data.compareTo(key) < 0 && curr.right != null) {
            curr = curr.right;
        }
        // If this.data > key, search to the left.
        else if(curr.data.compareTo(key) > 0) { 
            // If the right-most on the left side has bigger than the key, search left.
            if(curr.left != null && curr.left.getRightMost().data.compareTo(key) > 0) {
                curr = curr.left;
            }
            // If there's no left, or the right-most on the left branch is smaller than the key, we're at the successor.
            else {
                successor = curr.data;
                curr = null;
            }
        }
        // this.data == key...
        else {
            // so get the right-most data.
            if(curr.right != null) {
                successor = curr.right.getLeftMost().data;
            }
            // there is no successor.
            else {
                successor = null;
            }
            curr = null;
        }
    }
    return successor;
}

public static void main(String[] args) {
    Node<Integer> one, three, five, seven, two, six, four;
    one = new Node<Integer>(Integer.valueOf(1), null, null);
    three = new Node<Integer>(Integer.valueOf(3), null, null);
    five = new Node<Integer>(Integer.valueOf(5), null, null);
    seven = new Node<Integer>(Integer.valueOf(7), null, null);
    two = new Node<Integer>(Integer.valueOf(2), one, three);
    six = new Node<Integer>(Integer.valueOf(6), five, seven);
    four = new Node<Integer>(Integer.valueOf(4), two, six);
    Node<Integer> head = four;
    for(int i = 0; i <= 7; i++) {
        System.out.println(head.getSuccessor(i));
    }
}
}
Απαντήθηκε 27/04/2012 στις 15:47
πηγή χρήστη

ψήφοι
2

Με Binary Search Tree, ο αλγόριθμος για να βρει το επόμενο υψηλότερο κόμβος ενός συγκεκριμένου κόμβου είναι ουσιαστικά εύρεση της χαμηλότερης κόμβο του δικαιώματος υπο-δέντρο αυτού του κόμβου.

Ο αλγόριθμος μπορεί απλά να είναι απλά:

  1. Ξεκινήστε με το δεξί παιδί του συγκεκριμένου κόμβου (να είναι η προσωρινή τρέχοντος κόμβου)
  2. Εάν ο τρέχων κόμβος δεν έχει αριστερό παιδί, είναι το επόμενο υψηλότερο κόμβο.
  3. Εάν ο τρέχων κόμβος έχει ένα αριστερό παιδί, ο τρέχων κόμβος κάνει.

Επαναλάβετε 2 και 3 μέχρι να βρούμε το επόμενο υψηλότερο κόμβο.

Απαντήθηκε 02/11/2012 στις 20:13
πηγή χρήστη

ψήφοι
4

Κώδικα Python για να του Lasse του απάντηση :

def findNext(node):
  if node.rightChild != None:
    return findMostLeft(node.rightChild)
  else:
    parent = node.parent
    while parent != None:
      if parent.leftChild == node:
        break
      node = parent
      parent = node.parent
    return parent
Απαντήθηκε 12/01/2013 στις 23:25
πηγή χρήστη

ψήφοι
1

C διάλυμα ++ υποθέτοντας κόμβοι έχουν αριστερά, δεξιά, και η μητρική δείκτες:

Αυτό δείχνει τη λειτουργία Node* getNextNodeInOrder(Node)που επιστρέφει το επόμενο πλήκτρο του δυαδικού δένδρου αναζήτησης τάξης.

#include <cstdlib>
#include <iostream>
using namespace std;

struct Node{
    int data;
    Node *parent;
    Node *left, *right;
};

Node *createNode(int data){
    Node *node =  new Node();
    node->data = data;
    node->left = node->right = NULL;
    return node;
}

Node* getFirstRightParent(Node *node){
    if (node->parent == NULL)
        return NULL;

    while (node->parent != NULL && node->parent->left != node){
        node = node->parent;
    }
    return node->parent;
}
Node* getLeftMostRightChild(Node *node){
    node = node->right;
    while (node->left != NULL){
        node = node->left;
    }
    return node;
}
Node *getNextNodeInOrder(Node *node){
    //if you pass in the last Node this will return NULL
    if (node->right != NULL)
        return getLeftMostRightChild(node);
    else
        return getFirstRightParent(node);
}
void inOrderPrint(Node *root)
{
    if (root->left != NULL) inOrderPrint(root->left);
    cout << root->data << " ";
    if (root->right != NULL) inOrderPrint(root->right);
}

int main(int argc, char** argv) {
    //Purpose of this program is to demonstrate the function getNextNodeInOrder
    //of a binary tree in-order.  Below the tree is listed with the order
    //of the items in-order.  1 is the beginning, 11 is the end.  If you 
    //pass in the node 4, getNextNode returns the node for 5, the next in the 
    //sequence.

    //test tree:
    //
    //        4
    //      /    \
    //     2      11
    //    / \     /
    //   1  3    10
    //          /
    //         5
    //          \
    //           6 
    //            \
    //             8
    //            / \
    //           7  9


    Node *root = createNode(4);
    root->parent = NULL;

    root->left = createNode(2);
    root->left->parent = root;

    root->right = createNode(11);
    root->right->parent = root;

    root->left->left = createNode(1);
    root->left->left->parent = root->left;

    root->right->left = createNode(10);
    root->right->left->parent = root->right;

    root->left->right = createNode(3);
    root->left->right->parent = root->left;

    root->right->left->left = createNode(5);
    root->right->left->left->parent = root->right->left;

    root->right->left->left->right = createNode(6);
    root->right->left->left->right->parent = root->right->left->left;

    root->right->left->left->right->right = createNode(8);
    root->right->left->left->right->right->parent = 
            root->right->left->left->right;

    root->right->left->left->right->right->left = createNode(7);
    root->right->left->left->right->right->left->parent = 
            root->right->left->left->right->right;

    root->right->left->left->right->right->right = createNode(9);
    root->right->left->left->right->right->right->parent = 
            root->right->left->left->right->right;

    inOrderPrint(root);

    //UNIT TESTING FOLLOWS

    cout << endl << "unit tests: " << endl;

    if (getNextNodeInOrder(root)->data != 5)
        cout << "failed01" << endl;
    else
        cout << "passed01" << endl;

    if (getNextNodeInOrder(root->right) != NULL)
        cout << "failed02" << endl;
    else
        cout << "passed02" << endl;

    if (getNextNodeInOrder(root->right->left)->data != 11)
        cout << "failed03" << endl;
    else
        cout << "passed03" << endl;

    if (getNextNodeInOrder(root->left)->data != 3)
        cout << "failed04" << endl;
    else
        cout << "passed04" << endl;

    if (getNextNodeInOrder(root->left->left)->data != 2)
        cout << "failed05" << endl;
    else
        cout << "passed05" << endl;

    if (getNextNodeInOrder(root->left->right)->data != 4)
        cout << "failed06" << endl;
    else
        cout << "passed06" << endl;

    if (getNextNodeInOrder(root->right->left->left)->data != 6)
        cout << "failed07" << endl;
    else
        cout << "passed07" << endl;

    if (getNextNodeInOrder(root->right->left->left->right)->data != 7)
        cout << "failed08 it came up with: " << 
          getNextNodeInOrder(root->right->left->left->right)->data << endl;
    else
        cout << "passed08" << endl;

    if (getNextNodeInOrder(root->right->left->left->right->right)->data != 9)
        cout << "failed09 it came up with: " 
          << getNextNodeInOrder(root->right->left->left->right->right)->data 
          << endl;
    else
        cout << "passed09" << endl;

    return 0;
}

Ποια εκτυπώσεις:

1 2 3 4 5 6 7 8 9 10 11

unit tests: 
passed01
passed02
passed03
passed04
passed05
passed06
passed07
passed08
passed09
Απαντήθηκε 16/07/2013 στις 19:21
πηγή χρήστη

ψήφοι
0

Μπορείτε να διαβάσετε περισσότερες πληροφορίες εδώ (Rus πνεύμονα)

Node next(Node x)
   if x.right != null
      return minimum(x.right)
   y = x.parent
   while y != null and x == y.right
      x = y
      y = y.parent
   return y


Node prev(Node x)
   if x.left != null
      return maximum(x.left)
   y = x.parent
   while y != null and x == y.left
      x = y
      y = y.parent
   return y
Απαντήθηκε 07/10/2014 στις 11:25
πηγή χρήστη

ψήφοι
0

Αυτές οι απαντήσεις όλα φαίνονται υπερβολικά περίπλοκη για μένα. Εμείς πραγματικά δεν χρειάζεται γονέα δείκτες ή οποιεσδήποτε βοηθητικές δομές δεδομένων, όπως μια στοίβα. Το μόνο που χρειάζεται να κάνετε είναι να διασχίσει το δέντρο από τη ρίζα σε σειρά, που μια σημαία, το συντομότερο βρίσκουμε τον κόμβο-στόχο, και το επόμενο κόμβο στο δέντρο που επισκεπτόμαστε θα είναι ο κόμβος διάδοχο σειρά. Εδώ είναι μια γρήγορη και βρώμικη τακτική έγραψα επάνω.

Node* FindNextInorderSuccessor(Node* root, int target, bool& done)
{
    if (!root)
        return NULL;

    // go left
    Node* result = FindNextInorderSuccessor(root->left, target, done);
    if (result)
        return result;

    // visit
    if (done)
    {
        // flag is set, this must be our in-order successor node
        return root;
    }
    else
    {
        if (root->value == target)
        {
            // found target node, set flag so that we stop at next node
            done = true;
        }
    }

    // go right
    return FindNextInorderSuccessor(root->right, target, done);
}
Απαντήθηκε 09/12/2014 στις 05:29
πηγή χρήστη

ψήφοι
1

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

Ας πούμε ότι έχουμε έναν κόμβο R και θέλουμε τους στο διάδοχο σειρά που θα έχει τις ακόλουθες περιπτώσεις.

[1] Η ρίζα R έχει δικαίωμα κόμβο, οπότε το μόνο που χρειάζεται να κάνετε είναι να διασχίσει με το αριστερό πιο κόμβο της R-> δικαιώματος.

[2] Η ρίζα R δεν έχει δικαίωμα κόμβο, σε αυτή την περίπτωση θα διασχίζουν πίσω μέχρι το δέντρο μετά από τις μητρικές συνδέσεις μέχρι τον κόμβο R είναι ένα αριστερό παιδί του γονέα του, όταν αυτό συμβαίνει έχουμε το μητρικό κόμβο P όπως η εν διάδοχος σειρά .

[3] Βρισκόμαστε στην άκρα δεξιά κόμβο του δέντρου, στην περίπτωση αυτή δεν υπάρχει σε διάδοχος σειρά.

Η εφαρμογή βασίζεται στα εξής ορισμό κόμβο

class node
{
private:
node* left;
node* right;
node* parent
int data;

public:
//public interface not shown, these are just setters and getters
.......
};

//go up the tree until we have our root node a left child of its parent
node* getParent(node* root)
{
    if(root->parent == NULL)
        return NULL;

    if(root->parent->left == root)
        return root->parent;
    else
        return getParent(root->parent);
}

node* getLeftMostNode(node* root)
{
    if(root == NULL)
        return NULL;

    node* left = getLeftMostNode(root->left);
    if(left)
        return left;
    return root;
}

//return the in order successor if there is one.
//parameters - root, the node whose in order successor we are 'searching' for
node* getInOrderSucc(node* root)
{
    //no tree, therefore no successor
    if(root == NULL)
        return NULL;

    //if we have a right tree, get its left most node
    if(root->right)
        return getLeftMostNode(root->right);
    else
        //bubble up so the root node becomes the left child of its
        //parent, the parent will be the inorder successor.
        return getParent(root);
}
Απαντήθηκε 10/01/2015 στις 20:11
πηγή χρήστη

ψήφοι
0

λύση JavaScript - Αν το δεδομένο κόμβο έχει δικαίωμα κόμβο, στη συνέχεια επιστρέφουν το μικρότερο κόμβο στο δεξί υποδέντρο - Αν όχι, τότε υπάρχουν 2 δυνατότητες: - Το δεδομένο κόμβο είναι ένα αριστερό παιδί του γονέα κόμβο. Αν ναι, επιστρέψτε το γονικό κόμβο. Σε αντίθετη περίπτωση, το δεδομένο κόμβο είναι δικαίωμα του παιδιού της μητρικής κόμβο. Αν ναι, επιστρέψτε το δικαίωμα του παιδιού της μητρικής κόμβου

function nextNode(node) {
  var nextLargest = null;
  if (node.right != null) {
    // Return the smallest item in the right subtree

    nextLargest = node.right;
    while (nextLargest.left !== null) {
      nextLargest = nextLargest.left;
    }

    return nextLargest;
  } else {
    // Node is the left child of the parent
    if (node === node.parent.left) return node.parent;

    // Node is the right child of the parent
    nextLargest = node.parent;
    while (nextLargest.parent !== null && nextLargest !== nextLargest.parent.left) {
      nextLargest = nextLargest.parent
    }
    return nextLargest.parent;
  }
}
Απαντήθηκε 19/10/2015 στις 03:44
πηγή χρήστη

ψήφοι
0

Με αυτόν τον τρόπο σε Java

TreeNode getSuccessor(TreeNode treeNode) {
    if (treeNode.right != null) {
         return getLeftMostChild(treeNode.right);
    } else {
        TreeNode p = treeNode.parent;
        while (p != null && treeNode == p.right) { // traverse upwards until there is no parent (at the last node of BST and when current treeNode is still the parent's right child
            treeNode = p;
            p = p.parent; // traverse upwards
        }
        return p; // returns the parent node
    }
}

TreeNode getLeftMostChild(TreeNode treeNode) {
    if (treeNode.left == null) {
        return treeNode;
    } else {
        return getLeftMostChild(treeNode.left);
    }
}
Απαντήθηκε 22/11/2016 στις 04:58
πηγή χρήστη

ψήφοι
0

Μπορούμε να χωρίσουμε αυτό σε 3 περιπτώσεις:

  1. Αν ο κόμβος είναι ένας γονέας: Σε αυτή την περίπτωση θα βρούμε αν έχει το δικαίωμα κόμβο και διασχίζουν με το αριστερό παιδί του δικαιώματος κόμβου. Σε περίπτωση που το δικαίωμα κόμβος δεν έχει παιδιά, τότε η σωστή κόμβος είναι inorder διάδοχό του. Αν δεν υπάρχει σωστό κόμβο πρέπει να κινηθεί προς τα επάνω το δέντρο για να βρει το διάδοχο inorder.

  2. Αν ο κόμβος είναι ένα αριστερό παιδί: Σε αυτή την περίπτωση ο γονέας είναι ο διάδοχος inorder.

  3. Αν ο κόμβος (ονομάσουμε x) είναι δικαίωμα του παιδιού (άμεσης μητρικής της): Θα διασχίσει το δέντρο μέχρι να βρούμε έναν κόμβο του οποίου το αριστερό υποδέντρο έχει x.

Ακραία περίπτωση: Εάν ο κόμβος είναι το δεξιότερο κόμβο γωνία, δεν υπάρχει διάδοχος inorder.

Απαντήθηκε 30/11/2016 στις 10:12
πηγή χρήστη

ψήφοι
0

Κάθε «φροντιστήριο» που ελέγχονται στο google και όλες τις απαντήσεις σε αυτό το νήμα χρησιμοποιεί την εξής λογική: " Αν ο κόμβος δεν έχει το δικαίωμα του παιδιού στη συνέχεια της στη σειρά διάδοχος θα είναι ένας από τους προγόνους του, χρησιμοποιώντας μητρική σύνδεσμο κρατήσει ταξιδεύουν μέχρι. μπορείτε να πάρετε τον κόμβο που είναι το αριστερό παιδί του γονέα του. στη συνέχεια, αυτή η μητρική κόμβος θα είναι ο διάδοχος στην παραγγελία. "

Αυτό είναι το ίδιο με τη σκέψη « αν η μητρική μου είναι μεγαλύτερο από μένα, τότε είμαι το αριστερό παιδί » (ιδιοκτησίας ενός δυαδικού δένδρου αναζήτησης). Αυτό σημαίνει ότι μπορείτε απλά να περπατήσετε μέχρι τη μητρική αλυσίδα μέχρι το παραπάνω ακίνητο είναι αλήθεια. Η οποία με αποτέλεσμα τη γνώμη μου σε ένα πιο κομψό κώδικα.

Υποθέτω ότι ο λόγος για τον οποίο ο καθένας έχει τον έλεγχο « είμαι το αριστερό παιδί » κοιτάζοντας τα υποκαταστήματα και όχι τιμές στον κώδικα μονοπάτι που χρησιμοποιεί η μητρική συνδέσεις προέρχεται από το «δανεισμό» λογική από τον αλγόριθμο μη-link-to-γονέα.

Επίσης από την συμπεριλαμβάνονται παρακάτω κώδικα είναι εκεί μπορούμε να δούμε καμία ανάγκη για τη δομή των δεδομένων στοίβα όπως προτείνεται από άλλες απαντήσεις.

Μετά είναι μια απλή C λειτουργία ++ που λειτουργεί και για τις δύο περιπτώσεις χρήσης (με και χωρίς τη χρησιμοποίηση του συνδέσμου προς τη μητρική).

Node* nextInOrder(const Node *node, bool useParentLink) const
{
    if (!node)
        return nullptr;

    // when has a right sub-tree
    if (node->right) {
        // get left-most node from the right sub-tree
        node = node->right;
        while (node->left)
            node = node->left;
        return node;
    }

    // when does not have a right sub-tree
    if (useParentLink) {
        Node *parent = node->parent;
        while (parent) {
            if (parent->value > node->value)
                return parent;
            parent = parent->parent;
        }
        return nullptr;
    } else {
        Node *nextInOrder = nullptr;
        // 'root' is a class member pointing to the root of the tree
        Node *current = root;
        while (current != node) {
            if (node->value < current->value) {
                nextInOrder = current;
                current = current->left;
            } else {
                current = current->right;
            }
        }
        return nextInOrder;
    }
}

Node* previousInOrder(const Node *node, bool useParentLink) const
{
    if (!node)
        return nullptr;

    // when has a left sub-tree
    if (node->left) {
        // get right-most node from the left sub-tree
        node = node->left;
        while (node->right)
            node = node->right;
        return node;
    }

    // when does not have a left sub-tree
    if (useParentLink) {
        Node *parent = node->parent;
        while (parent) {
            if (parent->value < node->value)
                return parent;
            parent = parent->parent;
        }
        return nullptr;
    } else {
        Node *prevInOrder = nullptr;
        // 'root' is a class member pointing to the root of the tree
        Node *current = root;
        while (current != node) {
            if (node->value < current->value) {
                current = current->left;
            } else {
                prevInOrder = current;
                current = current->right;
            }
        }
        return prevInOrder;
    }
}
Απαντήθηκε 01/01/2017 στις 13:11
πηγή χρήστη

ψήφοι
0

C # εφαρμογή (μη αναδρομικό!) Για να βρείτε την «επόμενη» κόμβος ενός συγκεκριμένου κόμβου σε ένα δυαδικό δένδρο αναζήτησης, όπου κάθε κόμβος έχει μια σύνδεση με τη μητρική της.

    public static Node WhoIsNextInOrder(Node root, Node node)
    {
        if (node.Right != null)
        {
            return GetLeftMost(node.Right);
        }
        else
        {
            Node p = new Node(null,null,-1);
            Node Next = new Node(null, null, -1);
            bool found = false;
            p = FindParent(root, node);
            while (found == false)
                {
                    if (p.Left == node) { Next = p; return Next; }
                    node = p;
                    p = FindParent(root, node);
                }
            return Next;
        }
    }

    public static Node FindParent(Node root, Node node)
    {
        if (root == null || node == null)
        {
            return null;
        }
        else if ( (root.Right != null && root.Right.Value == node.Value) || (root.Left != null && root.Left.Value == node.Value))
        {
            return root;
        }
        else
        {
            Node found = FindParent(root.Right, node);

            if (found == null)
            {
                found = FindParent(root.Left, node);
            }

            return found;
        }
    }

    public static Node GetLeftMost (Node node)
    {
        if (node.Left == null)
        {
            return node;
        }
        return GetLeftMost(node.Left);
    }
Απαντήθηκε 16/03/2017 στις 07:15
πηγή χρήστη

ψήφοι
0

Μπορούμε να βρούμε τον διάδοχο σε O (log n) χωρίς τη χρήση μητρικών δείκτες (για μια ισορροπημένη δέντρο).

Η ιδέα είναι πολύ παρόμοια με όταν έχεις γονέα δείκτες.

Μπορούμε να ορίσουμε μια αναδρομική συνάρτηση που επιτυγχάνει αυτό ως εξής:

  • Εάν ο τρέχων κόμβος είναι ο στόχος, να επιστρέψει το πιο αριστερό / μικρότερη κόμβο του δικαιώματος υποδέντρο του, αν υπάρχει.
  • Recurse αριστερά αν ο στόχος είναι μικρότερο από το τρέχον κόμβο, και δεξιά αν είναι μεγαλύτερη.
  • Εάν ο στόχος είναι προς τα αριστερά και δεν έχουμε βρει έναν διάδοχο ακόμα, να επιστρέψει το τρέχον κόμβο.

Ψευδοκώδικας:

Key successor(Node current, Key target):
   if current == null
      return null
   if target == current.key
      if current.right != null
         return leftMost(current.right).key
      else
         return specialKey
   else
      if target < current.key
         s = successor(current.left, target)
         if s == specialKey
            return current.key
         else
            return s
      else
         return successor(current.right, target)

Node leftMost(Node current):
    while current.left != null
       current = current.left
    return current

Ζήστε Java demo .

Απαντήθηκε 31/12/2017 στις 16:10
πηγή χρήστη

ψήφοι
1

εμείς dont πρέπει γονέα σύνδεση ή στοίβα για να βρει το διάδοχο στην σειρά με O (log n) (υποθέτοντας ισορροπημένο δέντρο). Κρατήστε μια προσωρινή μεταβλητή με την πιο πρόσφατη τιμή που ανέκυψαν κατά τη διάσχιση inorder που είναι μεγαλύτερο από το κλειδί. αν inorder διάσχιση διαπιστώσει ότι ο κόμβος δεν έχει το δικαίωμα του παιδιού, τότε αυτό θα ήταν ο διάδοχος inorder. άλλο, το πιο αριστερό απόγονος του δικαιώματος του παιδιού.

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

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