Я создаю двоичный класс дерева поиска. Я получил все мои функции, работающие с 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;
}
Я добавил рабочее решение на основе псевдокода в ответе Никласа:
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;
}
Преемник 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;
Может быть, неплохо поставить туда некоторые нулевые проверки.
else
делом. Рассмотрим node
- это правильный узел. Затем к концу , while
цикл у вас есть свой родительский и node=node.getRight
дает исходный узел. Вместо этого вы должны были выглядеть «выше».
Возможный алгоритм:
Пример:
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
return node.parent
Я думаю, что приведенный выше код не будет работать для самого правого последнего узла. Вот улучшенная версия:
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;