我正在二元搜索树上做一个小型的Java工作但是当我将一个节点的递归插入实现到树中并显示它时,我什么也得不到。我已经有一段时间了,我不确定,但我认为这是一个传递参考问题。
这是我的代码:
public class BST {
private BSTNode root;
public BST() {
root = null;
}
public BSTNode getRoot() {
return root;
}
public void insertR( BSTNode root, Comparable elem ) {
if ( root == null ) {
root = new BSTNode( elem );
}
else {
if ( elem.compareTo( root.element ) < 0 ) {
insertR( root.left, elem );
} else {
insertR( root.right, elem );
}
}
}
public void printInOrder (BSTNode root) {
if (root != null) {
printInOrder(root.left);
System.out.println(root.element);
printInOrder(root.right);
}
}
}
class BSTNode {
protected Comparable element;
protected BSTNode left;
protected BSTNode right;
protected BSTNode ( Comparable elem ) {
element = elem;
left = null;
right = null;
}
}
我执行了一系列insertR,其中root是要插入的节点,elem是一个字符串,但它不打印任何内容,就像树根本没有填充一样。我确定这是我的递归插入的问题,但我不知道在哪里,我需要使用递归插入方法,返回任何我认为是不可能的。
任何帮助都会很棒。
答案 0 :(得分:2)
BSTNodes的左,右元素为空。您需要在插入之前创建它们。否则,他们会创建一个空的BSTNode()并插入它,而不连接到树的其余部分。
您可以更改行
if ( elem.compareTo( root.element ) < 0 ) {
insertR( root.left, elem );
} else {
insertR( root.right, elem );
}
到
if ( elem.compareTo( root.element ) < 0 ) {
if ( root.left == null )
root.left = new BSTNode( elem );
else
insertR( root.left, elem );
} else {
if ( root.right == null )
root.right = new BSTNode( elem );
else
insertR( root.right, elem );
}
答案 1 :(得分:1)
虽然递归插入BST似乎微不足道,但是很容易让一个参数传递错误,这会使你的尝试无效。要以递归方式调用插入函数,必须将对象BSTNode root
作为参数传递,并对其内容进行更改而不是其指向的内容。
在以下代码中,root = new BSTNode( elem );
仅更改局部变量root
指向的地址,并且this.root
无法看到更改。在分配之前,root
的值为null
,当BST为空时,该值已从this.root
复制。分配后,root
指向一些新创建的BSTNode
来自elem
的数据。代码的意图是使this.root
指向相同的新BSTNode
,但是没有办法通过使本地root
指向它来实现这一点。当insertR
返回时,this.root
仍然指向null
!!
同样的错误发生在insertR(root.left, elem);
和insertR(root.right, elem);
上。参数被传递,但由于没有进行内容更改,函数调用将返回,而没有更新信息到BST。
public void insert(Comparable elem) {
insertR(this.root, elem);
}
public void insertR( BSTNode root, Comparable elem ) {
if ( root == null ) {
root = new BSTNode( elem );
}
else {
if ( elem.compareTo( root.element ) < 0 ) {
insertR( root.left, elem );
} else {
insertR( root.right, elem );
}
}
}
要递归更改BST,应对对象包含的变量进行更改,而不是对象变量指向的变量。因此,当this.root
为null
时,您应该在其他地方处理第一个插入而不是insertR
内部,如下所示:
public void insert(Comparable elem) {
if (this.root == null) {
this.root = new BSTNode(elem);
} else {
insertR(this.root, elem);
}
}
Arcturus用于其他插入的代码是正确的,因为对root
内容所做的更改会立即传播到this.root
,因为它们指向同一个BSTNode
对象。当然,此处root
必须不是null
,因为null
案例已在上面的代码中处理过,所以会感到满意。
if ( elem.compareTo( root.element ) < 0 ) {
if ( root.left == null )
root.left = new BSTNode( elem );
else
insertR( root.left, elem );
} else {
if ( root.right == null )
root.right = new BSTNode( elem );
else
insertR( root.right, elem );
}
答案 2 :(得分:0)
这将设置BST根目录并允许该类正常工作,更改
if ( root == null ) {
root = new BSTNode( elem );
}
到
if ( root == null ) {
root = new BSTNode( elem );
if ( root.element != null ) {
this.root = root;
}
}