Есть ли лучший способ найти наименьший общий предок?

голоса
3

Я знаю , что подобные вопросы были заданы раньше, но я думаю , что мое решение гораздо проще. Особенно по сравнению с Википедией .

Пожалуйста, доказать, что я не прав!

Если у вас есть дерево с узлами, которые имеют заданную структуру данных:

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

Вы могли бы написать такую ​​функцию:

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

Этот код очень прост и худший случай O (п), в среднем случае это, вероятно, O (LOGN), особенно если дерево сбалансировано (где п число узлов в дереве).

Задан 30/10/2010 в 03:26
источник пользователем
На других языках...                            


3 ответов

голоса
5

Ваш алгоритм выглядит хорошо для меня, по крайней мере, я не мог придумать ничего лучшего. Обратите внимание, что вам не нужен родительский указатель; вместо этого вы можете идти вниз по дереву, начиная от корня, и найти первый узел, ключ лежит между двумя начальными ключами.

Тем не менее, ваша проблема не имеет ничего общего с тем, Тарьян решена. Прежде всего, вы считаете, бинарные деревья, и он считает, п-арные деревья; но это, вероятно, деталь. Что еще более важно, вы считаете дерева поиска, в то время как Тарьян считает общие дерева (не упорядочивания по клавишам). Ваша задача намного проще, потому что, в зависимости от ключа, вы можете догадаться, где некоторый узел должен быть в дереве.

Ответил 01/11/2010 в 20:18
источник пользователем

голоса
1

Нет, я прошу прощения. Но ваш алгоритм не хорошо. принять следующую BST:

10
  \
   \
   15
  / \
 14 16

you'r алгоритм возвратит 10 в качестве наименьшего общего предка.

Таким образом, вы могли бы написать алгоритм, взять, скажем, левый узел и чем перейти к родителю и запустить в заказе на него и что проверки, если права было в выходе в порядка

Ответил 15/05/2013 в 23:02
источник пользователем

голоса
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


}
Ответил 04/06/2013 в 08:52
источник пользователем

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