#java #data-structures #binary-search-tree
Вопрос:
Почему я получаю false
во время работы search(7)
? Я попробовал рекурсивное решение, оно работает нормально.. попытка реализации с помощью цикла не удалась
public class BST {
class Node {
int data;
Node left , right;
public Node(int data) {
this.data = data;
this.left = this.right = null;
}
}
Node root;
public BST() {
this.root = null;
}
public void insert(int data) {
// create a new node and start iteration from root node
Node newNode = new Node(data);
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
currentNode = newNode;
break;
}
if (data < currentNode.data) { // if data is less go left
currentNode = currentNode.left;
} else if (data > currentNode.data) { // if data is greater go right
currentNode = currentNode.right;
} else { // do nothing for duplicates
break;
}
}
}
public boolean search(int data) {
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
return false;
}
if (data == currentNode.data) {
return true;
} else if (data < currentNode.data) {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
}
}
public static void main(String... args) {
BST tree = new BST();
tree.insert(15);
tree.insert(7);
System.out.println(tree.search(7));
}
}
Ответ №1:
Проблема кроется внутри insert
метода — вы неправильно вставляете узлы внутри дерева.
- Если дерево пустое, вы должны назначить
this.root
, нетcurrentNode
. НазначениеcurrentNode
не влияет наthis.root
.В настоящее время ваш код не вставляет какой-либо узел внутри дерева; он просто присваивает новый узел локальной переменной
insert
метода, т. Е.currentNode
. - Если условие
data < currentNode.data
истинно, то вам нужно проверитьcurrentNode.left
, так этоnull
или нет. Если это так, то свяжите новый узел с текущим узлом, как показано ниже:currentNode.left = newNode;
Если
currentNode.left
нетnull
, то выполните следующие действия:currentNode = currentNode.left;
В настоящее время ваш код перемещает значение
currentNode
tonull
, а затем присваивает значениеnewNode
tocurrentNode
без ссылки на его родительский узел в дереве. - Сделайте
data > currentNode.data
также шаг 2 для.
Измените реализацию insert
метода, как показано ниже:
public void insert(int data) {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
return;
}
Node currentNode = this.root;
while (true) {
if (data < currentNode.data) {
if (currentNode.left == null) {
currentNode.left = newNode;
} else {
currentNode = currentNode.left;
}
} else if (data > currentNode.data) {
if (currentNode.right == null) {
currentNode.right = newNode;
} else {
currentNode = currentNode.right;
}
} else {
break;
}
}
}
Комментарии:
1. итак, что я делал, это перемещал указатель в нуль без ссылки на его родительский узел правильно? Таким образом, я не смог создать края дерева?
2. Да, в этом была одна из проблем. Другая проблема заключалась в том, что, когда дерево пусто, ваш код не обновлял
this.root
; вместо этого он назначилnewNode
локальную переменнуюinsert
метода, т. Е.currentNode
.