Existuje lepší způsob, jak najít nejnižší společný předek?

hlasů
3

Vím, že podobné otázky byly požádány dříve, ale myslím, že moje řešení je mnohem jednodušší. Zejména ve srovnání s Wikipedie .

Prosím dokázat mě špatně!

Máte-li strom s uzly, které mají danou datovou strukturu:

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

Dalo by se napsat funkci, jako je tento:

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

Tento kód je velice jednoduché a nejhorší případ je O (n), průměr případě je zřejmě O (logn), a to zejména v případě, že strom je dáno (kde n je počet uzlů ve stromu).

Položena 30/10/2010 v 03:26
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
5

Váš algoritmus vypadá dobře pro mě, alespoň jsem nemohl vymyslet nic lepšího. Všimněte si, že nemusíte mateřskou ukazatel; místo toho můžete jít dolů strom od kořene, a najít první uzel, jehož klíč položí mezi oběma počátečními klíči.

Nicméně, váš problém nemá nic společného s jedním Tarjanův vyřešen. Za prvé, můžete zvážit binární stromy a on se domnívá, n-ary stromy; ale to je pravděpodobně detail. Ještě důležitější je, můžete zvážit vyhledávací stromy, zatímco Tarjanův domnívá obecných stromy (bez objednání na klávesách). Váš problém je mnohem jednodušší, protože v závislosti na klíči, můžete hádat, kde musí být ve stromu určitý uzel.

Odpovězeno 01/11/2010 v 20:18
zdroj uživatelem

hlasů
1

Ne, omlouvám se. Ale váš algoritmus není dobrá. přijmout následující BST:

10
  \
   \
   15
  / \
 14 16

you'r algoritmus vrátí 10 za nejmenšího společného předka.

Tak, můžete napsat algoritmus, který přijmout, řekněme, levý uzel a pak jít do své mateřské společnosti a spuštění in-pořadí na něm a že pro zjištění, zda právo bylo ve výstupu v řádu

Odpovězeno 15/05/2013 v 23:02
zdroj uživatelem

hlasů
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


}
Odpovězeno 04/06/2013 v 08:52
zdroj uživatelem

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