问题描述
我在java中使用链表创建了一个二叉树,它根据树的高度插入值,即高度是偶数还是奇数。我写了一个代码,它最初没有用于将值插入根节点和进一步的左或右子树节点的临时节点。但是当我显示这棵树时,输出没有根节点,就好像它被覆盖了一样。
下面是我的初始程序的代码。专注于 public void insert_node()
功能。
import java.util.Scanner;
public class binary_tree {
private TreeNode root;
private int height = 0;
public static class TreeNode {
private int data;
private TreeNode left;
private TreeNode right;
public TreeNode(int user_input) {
this.data = user_input;
}
}
public void insertNode(TreeNode newnode) { // HERE....I have used only root.
if (root == null) {
root = newnode;
height += 1;
return;
}
if (height % 2 != 0) {
System.out.println(height);
while (root.left != null) {
root = root.left;
}
root.left = newnode;
height += 1;
return;
}
while (root.right != null) {
root = root.right;
}
root.right = newnode;
height += 1;
}
public void display(TreeNode rootnode) {
TreeNode temp = rootnode;
if (temp == null)
System.out.println("Tree Empty !!!");
else {
System.out.println("press 1 for LEFT SUBTREE \npress 2 for RIGHT SUBTREE.");
Scanner sc = new Scanner(system.in);
int ch = sc.nextInt();
while (temp != null) {
System.out.println(temp.data + " $");
if (ch == 1)
temp = temp.left;
else
temp = temp.right;
}
}
System.out.println("Height of the tree = " + height);
}
public static void main(String[] args) {
// Todo Auto-generated method stub
binary_tree bt = new binary_tree();
TreeNode newNode = new TreeNode(50);
bt.insertNode(newNode);
TreeNode newNode2 = new TreeNode(10);
bt.insertNode(newNode2);
TreeNode newNode3 = new TreeNode(100);
bt.insertNode(newNode3);
TreeNode newNode4 = new TreeNode(5);
bt.insertNode(newNode4);
TreeNode newNode5 = new TreeNode(1000);
bt.insertNode(newNode5);
bt.display(bt.root);
}
}
press 1 for LEFT SUBTREE
press 2 for RIGHT SUBTREE.
3
10 $
1000 $
Height of the tree = 5
您可以在上面的代码中看到,50 $
丢失了,它应该是根节点。
现在,如果我使用一个临时节点(在我的情况下是 current_node
),那么这个根节点会以某种方式维持。请参阅下面的代码。
import java.util.Scanner;
public class binary_tree {
private TreeNode root;
private int height = 0;
public static class TreeNode {
private int data;
private TreeNode left;
private TreeNode right;
public TreeNode(int user_input) {
this.data = user_input;
}
}
public void insertNode(TreeNode newnode) {
TreeNode current_node = root; //THIS IS THE TEMPORARY NODE
if (current_node == null) {
root = newnode;
height += 1;
return;
}
if (height % 2 != 0) {
System.out.println(height);
while (current_node.left != null) {
current_node = current_node.left;
}
current_node.left = newnode;
height += 1;
return;
}
while (current_node.right != null) {
current_node = current_node.right;
}
current_node.right = newnode;
height += 1;
}
public void display(TreeNode rootnode) {
TreeNode temp = rootnode;
if (temp == null)
System.out.println("Tree Empty !!!");
else {
System.out.println("press 1 for LEFT SUBTREE \npress 2 for RIGHT SUBTREE.");
Scanner sc = new Scanner(system.in);
int ch = sc.nextInt();
while (temp != null) {
System.out.println(temp.data + " $");
if (ch == 1)
temp = temp.left;
else
temp = temp.right;
}
}
System.out.println("Height of the tree = " + height);
}
public static void main(String[] args) {
// Todo Auto-generated method stub
binary_tree bt = new binary_tree();
TreeNode newNode = new TreeNode(50);
bt.insertNode(newNode);
TreeNode newNode2 = new TreeNode(10);
bt.insertNode(newNode2);
TreeNode newNode3 = new TreeNode(100);
bt.insertNode(newNode3);
TreeNode newNode4 = new TreeNode(5);
bt.insertNode(newNode4);
TreeNode newNode5 = new TreeNode(1000);
bt.insertNode(newNode5);
bt.display(bt.root);
}
}
press 1 for LEFT SUBTREE
press 2 for RIGHT SUBTREE.
3
50 $
100 $
1000 $
Height of the tree = 5
那么谁能告诉我这里发生了什么? current_node
有什么不同?
解决方法
为什么在链表的节点中插入值时需要一个临时节点?
因为你要遍历这里的树叶:
while (current_node.left != null) {
current_node = current_node.left;
}
current_node.left = newnode;
height += 1;
在这几行代码中,您试图找到最左边的叶子以插入 newnode
,对吗?您想使用一个变量来跟踪您当前所在的节点,并通过执行 someVariable = someVariable.left;
来“向左走”。
您可以使用 root
来跟踪您所在的位置,但是 root
已经有一个目的 - 记录树的根!如果你做了root = root.left;
,你就是在让原来的根的左节点成为新的根!假设你的树是:
50
/ \
10 100
执行 root = root.left
会删除大部分内容:
10
这是有问题的,因为这意味着您的树基本上“忘记”了树的一部分。从技术上讲,50 和 100 节点仍然存在并且 50 仍然连接到 10,但您的 binary_tree
对象无法再访问它。它具有的唯一访问点是 root
,您现在已将其设置为节点 10。
在您的程序中实际发生的是:它正确插入了 50、10 和 100,然后在添加 5 时尝试向下遍历左子树。这使根为“10”,加上 5 变为:
10
/
5
然后正确添加 1000:
10
/ \
5 1000
因此它打印 10 和 1000。
使用全新的变量可以解决这个问题,因为全新的变量与root
无关。