Y at-il une meilleure façon de trouver le plus bas ancêtre commun?

voix
3

Je sais que des questions similaires ont été posées, mais je pense que ma solution est beaucoup plus simple. Surtout par rapport à Wikipedia .

S'il vous plaît me prouver!

Si vous avez un arbre avec des nœuds qui ont la structure de données donnée:

struct node
{
    node * left;
    node * right;
    node * parent;
    int key;
}

Vous pouvez écrire une fonction comme ceci:

node* LCA(node* m, node* n)
{
    // determine which of the nodes is the leftmost
    node* left = null;
    node* right = null;
    if (m->key < n->key)
    {
        left = m;
        right = n;
    }
    else
    {
        left = n;
        right = m;
    }
    // start at the leftmost of the two nodes,
    // keep moving up the tree until the parent is greater than the right key
    while (left->parent && left->parent->key < right->key)
    {
        left = left->parent;
    }
    return left;
}

Ce code est assez simple et le pire des cas est O (n), cas en moyenne, il est probablement O (logn), surtout si l'arbre est équilibré (où n est le nombre de noeuds dans l'arborescence).

Créé 30/10/2010 à 03:26
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
5

Votre algorithme semble correct pour moi, au moins je ne pouvais pas penser à quelque chose de mieux. Notez que vous n'avez pas besoin du pointeur de parent; au contraire, vous pouvez descendre l'arbre à partir de la racine, et trouver le premier noeud dont la clé se trouve entre les deux clés initiales.

Cependant, votre problème n'a rien à voir avec celui Tarjan résolu. Tout d'abord, on considère les arbres binaires et il considère les arbres n-aire; mais cela est probablement un détail. Plus important encore, on considère des arbres de recherche, tandis que Tarjan considère arbres général (pas de commande sur les touches). Votre problème est beaucoup plus simple, parce que, en fonction de la clé, vous pouvez deviner où un certain nœud doit être dans l'arbre.

Créé 01/11/2010 à 20:18
source utilisateur

voix
1

Non je suis désolé. Mais votre algorithme est pas bon. prendre la BST suivante:

dix
  \
   \
   15
  / \
 14 16

you'r algorithme retour 10 comme ancêtre commun le plus bas.

Ainsi, vous pouvez écrire algorithme prendre, par exemple, le nœud gauche et que d'aller à son parent et exécuter dans l'ordre sur elle et que l'enregistrement si le droit était dans la sortie du en ordre

Créé 15/05/2013 à 23:02
source utilisateur

voix
1
Node* getAncestor( Node* root, Node* node1 , Node* node2 )
{
    if( root->val > node1->val && root->val > node2->val )
        getAncestor( root->left , node1 , node2 );
    //recursive call with left subtree

    if( root->val < node1->val && root->val < node2->val )
        getAncestor( root->right , node1 , node2 );
    //recursive call with right subtree

    return root ;
    //returning the root node as ancestor

    //initial call is made with the tree's root node
    //node1 and node2 are nodes whose ancestor is to be located


}
Créé 04/06/2013 à 08:52
source utilisateur

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