二叉搜索树不会添加新节点?
Binary Search tree won't add new nodes?
我正在尝试编写一个递归方法来将节点添加到二叉搜索树(不允许重复)。由于某种原因,该方法仅在树为空时有效,否则它会打印出 "Duplicate" (即使它不是重复的)。我是编程新手,希望能提供解决此问题的帮助和提示。谢谢。
//add new node to the tree
public void add(int data) {
Node<Integer> newNode = new Node<>(data); //create new node with the data
//if the tree is empty, the newNode becomes the root
if (size() == 0) {
root = newNode;
return;
}
//otherwise, check if node should be placed to right or left
add(data, root);
}
private void add(int data, Node<Integer> node) {
//base case - found an empty position
if (node == null) {
node = new Node<Integer>(data);
}
if (data < node.data) {
add(data, node.left);
}
else if (data > node.data) {
add(data, node.right);
}
else if (data == node.data) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
}
当您的树为空时,节点会正确添加到其中。第一个add(int data)
函数没问题。
第二个 add(int data, Node<Integer> node)
函数存在问题。如果树已经有一个元素,则调用此方法。如果传递的节点大于或小于传递的值,则使用当前节点的左或右子节点再次调用该函数。该值可能(最终会)为空。这导致在您的方法的基本情况下创建一个节点,这导致满足此 data == node.data
条件,因为该节点确实是使用数据值创建的。因此您会收到错误消息。
为了解决这个问题,第二个函数可以改变如下:
private void add(int data, Node<Integer> node) {
if (data < node.data) {
if (node.left != null) {
add(data, node.left);
} else {
node.left = new Node<>(data);
}
}
else if (data > node.data) {
if (node.right != null) {
add(data, node.right);
} else {
node.right = new Node<>(data);
}
add(data, node.right);
}
else if (data == node.data) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
}
看到基本案例已被删除。如果遇到过,基本情况不会为我们提供对任何树节点的引用。因此,向树添加 data
是不可能的(节点参数 绝不能 为空)。
此外,如果子项为空,代码会将 data
作为子项添加到 node
。这保证了该方法不会使用空 node
参数递归,并且更重要的是将 data
添加到其正确的位置。
在递归结束时,您没有返回 BST 的实际根。 "root" 您拥有的对象指向最后插入的节点。因此,每次您尝试插入相同的值时,它都会插入到最后插入的具有相同值的节点之后。这是我的实现:
class BinarySearchTree {
class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
Node root;
BinarySearchTree() {
root = null;
}
void add(int data) {
root = add(root, data);
}
Node add(Node root, int data) {
if (root == null) {
root = new Node(data);
return root;
}
if (data < root.key)
root.left = add(root.left, data);
else if (data > root.key)
root.right = add(root.right, data);
else if( data==root.key) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
return root;
}
void inorder() {
inorderRec(root);
}
void inorderRec(Node root) {
if (root != null) {
inorderRec(root.left);
System.out.println(root.key);
inorderRec(root.right);
}
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.add(50);
tree.add(30);
tree.add(20);
tree.add(20);
// print inorder traversal of the BST
System.out.println("Inorder traversal");
tree.inorder();
tree.add(40);
tree.add(40);
tree.add(70);
tree.add(60);
tree.add(80);
System.out.println("Inorder traversal");
// print inorder traversal of the BST
tree.inorder();
}
}
我正在尝试编写一个递归方法来将节点添加到二叉搜索树(不允许重复)。由于某种原因,该方法仅在树为空时有效,否则它会打印出 "Duplicate" (即使它不是重复的)。我是编程新手,希望能提供解决此问题的帮助和提示。谢谢。
//add new node to the tree
public void add(int data) {
Node<Integer> newNode = new Node<>(data); //create new node with the data
//if the tree is empty, the newNode becomes the root
if (size() == 0) {
root = newNode;
return;
}
//otherwise, check if node should be placed to right or left
add(data, root);
}
private void add(int data, Node<Integer> node) {
//base case - found an empty position
if (node == null) {
node = new Node<Integer>(data);
}
if (data < node.data) {
add(data, node.left);
}
else if (data > node.data) {
add(data, node.right);
}
else if (data == node.data) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
}
当您的树为空时,节点会正确添加到其中。第一个add(int data)
函数没问题。
第二个 add(int data, Node<Integer> node)
函数存在问题。如果树已经有一个元素,则调用此方法。如果传递的节点大于或小于传递的值,则使用当前节点的左或右子节点再次调用该函数。该值可能(最终会)为空。这导致在您的方法的基本情况下创建一个节点,这导致满足此 data == node.data
条件,因为该节点确实是使用数据值创建的。因此您会收到错误消息。
为了解决这个问题,第二个函数可以改变如下:
private void add(int data, Node<Integer> node) {
if (data < node.data) {
if (node.left != null) {
add(data, node.left);
} else {
node.left = new Node<>(data);
}
}
else if (data > node.data) {
if (node.right != null) {
add(data, node.right);
} else {
node.right = new Node<>(data);
}
add(data, node.right);
}
else if (data == node.data) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
}
看到基本案例已被删除。如果遇到过,基本情况不会为我们提供对任何树节点的引用。因此,向树添加 data
是不可能的(节点参数 绝不能 为空)。
此外,如果子项为空,代码会将 data
作为子项添加到 node
。这保证了该方法不会使用空 node
参数递归,并且更重要的是将 data
添加到其正确的位置。
在递归结束时,您没有返回 BST 的实际根。 "root" 您拥有的对象指向最后插入的节点。因此,每次您尝试插入相同的值时,它都会插入到最后插入的具有相同值的节点之后。这是我的实现:
class BinarySearchTree {
class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
Node root;
BinarySearchTree() {
root = null;
}
void add(int data) {
root = add(root, data);
}
Node add(Node root, int data) {
if (root == null) {
root = new Node(data);
return root;
}
if (data < root.key)
root.left = add(root.left, data);
else if (data > root.key)
root.right = add(root.right, data);
else if( data==root.key) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
return root;
}
void inorder() {
inorderRec(root);
}
void inorderRec(Node root) {
if (root != null) {
inorderRec(root.left);
System.out.println(root.key);
inorderRec(root.right);
}
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.add(50);
tree.add(30);
tree.add(20);
tree.add(20);
// print inorder traversal of the BST
System.out.println("Inorder traversal");
tree.inorder();
tree.add(40);
tree.add(40);
tree.add(70);
tree.add(60);
tree.add(80);
System.out.println("Inorder traversal");
// print inorder traversal of the BST
tree.inorder();
}
}