Поиск преемника Inorder в бинарном дереве поиска [дубликаты]

1

Я создаю двоичный класс дерева поиска. Я получил все мои функции, работающие с Accepter.

Мой вход в дерево 30 10 45 38 20 50 25 33 8 12

Когда я печатаю обход Inorder, он появляется как

8 10 12 20 25 30 33 38 45 50

Когда я ввожу значение 8, он говорит, что его преемник равен 12. То же самое для самого входа 10 и 12.

Когда я ввожу значение 33, он говорит, что преемник равен 50. Какой его нет.

Кажется, я не могу это исправить. Любая помощь предложения будет оценена по достоинству.

Я называю это главным:

BinarySearchTree BST = new BinarySearchTree(array);

BST.getSeccessor(a); // where a is user input to find it successor

Следующий мой код...

 public TreeNode Successor(TreeNode node) {
        if (node == null) 
         return node; 
        if (node.right != null) {
            return leftMostNode(node.right);
        }
        TreeNode y = node.parent;
        while (null != y && (y.right).equals(node)) {
            node = y;
            y = y.parent;
        }
      return y;
    }

    public static TreeNode leftMostNode(TreeNode node) {
     if (null == node) { return null; }

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

    /** Search value in Tree need for Successor **/
    public TreeNode Search(int key) {
        TreeNode node = root;                           
        while (node != null) {
            if (key < node.value) {                     
                node = node.left;
            } else if (key  > node.value) {             
                node = node.right;
            } 
            return node;
        }
        return null;
    }

    /** Returns Successor of given value **/
    public int getSuccessor(int val) {
        TreeNode node = Successor(Search(val));
        return node.value; 
    }
  • 0
    Пожалуйста, смотрите решение в Java. Не стесняйтесь проверить, работает ли он.
Теги:
algorithm
binary-search-tree
binary-tree

4 ответа

3
Лучший ответ

Я добавил рабочее решение на основе псевдокода в ответе Никласа:

public TreeNode successor(TreeNode node) {
    if (node == null)
        return node;

    if (node.right != null) {
        return leftMostNode(node.right);
    }

    while (null != node.parent /*while we are not root*/ 
            && node.parent.right == node) /* and while we are "right" node */ {

        node = node.parent; // go one level up
    }

    return node.parent;
}

Чтобы это сработало, вы должны исправить реализацию некоторых ваших методов (см. Ниже):

/** Search value in Tree need for Successor **/
public TreeNode search(int key) {
    TreeNode node = root;
    while (node != null 
            && key != node.value) {

        if(key < node.value) {
            node = node.left;
        } else if (key > node.value) {
            node = node.right;
        }
    }
    return node;
}

/** Returns Successor of given value **/
public int getSuccessor(int val) {
    TreeNode node; 
    if (null == (node = search(val))
            || (null == (node = successor(node))) {
        // either val is not in BST, or it is the last value-> no successor
        return ERROR_CODE; // -1, for instance;
    }

    return node.value;
}
  • 0
    Поэтому я вставил именно то, что вы меня, и заменил «ERROR_CODE» на -1, потому что он показывал ошибку. После этого я ввожу те же числа, что и в исходной задаче, и там написано, что преемник 8, 12, 25, 38 равен -1?
  • 1
    Возможно, у вас есть проблемы с построением вашего дерева. Я запустил этот код, и все работает отлично, вы можете увидеть его здесь: ideone.com/HpFU1A
Показать ещё 1 комментарий
3

Преемник inorder будет

if (node.hasRight())
    node = node.getRight();
else {
    while (node.isRightChild())
        node = node.getParent();
    return node.getParent();
}
while (node.hasLeft())
    node = node.getLeft();
return node;

Может быть, неплохо поставить туда некоторые нулевые проверки.

  • 0
    Есть проблема с вашим else делом. Рассмотрим node - это правильный узел. Затем к концу , while цикл у вас есть свой родительский и node=node.getRight дает исходный узел. Вместо этого вы должны были выглядеть «выше».
  • 0
    @kiruwka просмотреть изменения
Показать ещё 12 комментариев
3

Возможный алгоритм:

  1. Если у вас есть непустое правое поддерево, то преемником является наименьшее значение в этом поддереве
  2. В противном случае поднимитесь по дереву, если вы больше не являетесь правым ребенком вашего родителя или пока не достигнете корня
  3. Если вы сейчас находитесь в корне, у вас нет преемника. В противном случае поднимитесь еще на один шаг, и вы на преемнике

Пример:

if node.right != null
    return leftmostInSubtree(node.right)
while node != root && node.parent.right == node
    node = node.parent
if node == root
    return null
return node.parent
  • 0
    Это тоже не правильно. последняя строка должна return node.parent
  • 0
    @kiruwka Хорошее наблюдение :)
Показать ещё 4 комментария
0

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

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

else if(node.parent==root)
return null;
else if(node==node.parent.left)
node=node.parent;
else
{
while(node.parent!=null)
node=node.parent
}

return node;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню