算法二叉搜索树的实现与java
我正在尝试使用Cormen的伪代码实现BST算法,但仍然存在问题
以下是我的节点代码:
public class Node {
Node left;
Node right;
int value;
Node(int value){
this.value = value;
this.left = null;
this.right = null;
}
}
对于Bstree:
public class Btree {
Node root;
Btree(){
this.root = null;
}
public static void inorderWalk(Node n){
if(n != null){
inorderWalk(n.left);
System.out.print(n.value + " ");
inorderWalk(n.right);
}
}
public static Node getParent(Btree t, Node n){
Node current = t.root;
Node parent = null;
while(true){
if (current == null)
return null;
if( current.value == n.value ){
break;
}
if (current.value > n.value){
parent = current;
current = current.left;
}
else{ //(current.value < n.value)
parent = current;
current = current.right;
}
}
return parent;
}
public static Node search(Node n,int key){
if(n == null || key == n.value ){
return n;
}
if(key < n.value){
return search(n.left,key);
}
else{
return search(n.right,key);
}
}
public static Node treeMinimum(Node x){
if(x == null){
return null;
}
while(x.left != null){
x = x.left;
}
return x;
}
public static Node treeMaximum(Node x){
if(x == null){
return null;
}
while(x.right != null){
x = x.right;
}
return x;
}
public static Node treeSuccessor(Btree t,Node x){
if (x.right == null){
return treeMinimum(x.right);
}
Node y = getParent(t,x);
while(y != null && x == y.right){
x = y;
y = getParent(t,y);
}
return y;
}
public static Btree insert(Btree t,Node z){
Node y = null;
Node x = t.root;
while(x != null){
y = x;
if(z.value < x.value)
x = x.left;
else
x = x.right;
}
Node tmp = getParent(t,z);
tmp = y;
if(y == null){
t.root = z;
}
else if(z.value < y.value)
y.left = z;
else
y.right = z;
return t;
}
public static Btree delete(Btree t,Node z){
Node y,x;
if (z.left == null || z.right == null)
y = z;
else
y = treeSuccessor(t,z);
if (y.left != null)
x = y.left;
else
x = y.right;
if (x != null){
Node tmp = getParent(t,x);
tmp = getParent(t,y);
}
if (getParent(t,y) == null ){
t.root = x;
}
else{
if( y == getParent(t,y).left ){
getParent(t,y).left = x;
}
else{
getParent(t,y).right = x;
}
}
if(y != z){
z.value = y.value;
}
return t;
}
public static void main(String[] args){
Btree test = new Btree();
Node n1 = new Node(6);
Node n2 = new Node(3);
Node n3 = new Node(9);
Node n4 = new Node(1);
Node n5 = new Node(16);
Node n6 = new Node(4);
Node n7 = new Node(2);
Node n8 = new Node(11);
Node n9 = new Node(13);
test = insert(test,n1);
test = insert(test,n2);
test = insert(test,n3);
test = insert(test,n4);
test = insert(test,n5);
test = insert(test,n6);
test = insert(test,n7);
test = insert(test,n8);
test = insert(test,n9);
inorderWalk(test.root);
System.out.println();
test = delete(test,n8);
inorderWalk(test.root);
System.out.println();
test = delete(test,n5);
inorderWalk(test.root);
System.out.println();
test = delete(test,n2);
inorderWalk(test.root);
System.out.println();
test = delete(test,n1);
inorderWalk(test.root);
}
}
主要问题是删除部分,有时它按预期工作,有时删除错误,有时删除空指针异常。问题是什么
附:这不是家庭作业
# 1 楼答案
首先,您的实现与面向对象无关(除了使用对象)。例如,插入和删除操作应该在树上操作
此外,我建议将节点类实现为树类的静态成员
# 2 楼答案
代码中的一些直接问题:你的
treeSuccessor
以当然应该是
if (x.right != null)
你的
insert
代码有以下行分配给
tmp
并立即再次分配给它。在我看来,你根本不需要这些行,因为你不再使用tmp
。此时,y
是插入其子节点z
的节点,所以只需删除这些行即可同样,在
delete
中,您有行实际上你什么都不做,因为
tmp
在这个片段之外是不可见的。然后,在delete
中,重复getParent(t,y)
表达式,这可能是一个昂贵的操作,因此只需计算一次,并将其分配给某个变量但总体而言,您的代码虽然看起来是正确的(可能除了
delete
,我不完全理解它,但看起来可疑),但与典型的二叉树代码不太相似。你并不真的需要getParent
和treeSuccessor
方法来实现search
、insert
和delete
。对search
的基本结构也适用于其他结构,但有以下修改:insert
时,当您到达null
链接时,不要返回null
,而是将元素插入到该点delete
,当您找到元素时,如果它只有一个子元素(或没有子元素),则将其替换为该子元素;如果它有两个子元素,则将其替换为左子树的最大值或右子树的最小值除此之外,这两种方法都需要在下降到树中时跟踪父节点,但这是对
search
进行的唯一修改。特别是,永远不需要在树中往上走(这treeSuccessor
就可以了)# 3 楼答案
我得站在Anon一边去重写。空指针来自
getParent
函数(它显式地返回空值以及其他内容)。因此,我将从这里开始,并修复函数,以便它们返回一件事,并且只在函数末尾返回一件事# 4 楼答案
。。。你的删除代码怎么了?这没有多大意义。我会考虑用更合乎逻辑的方式改写它。没有无意义的单字母变量名。并添加评论
一种可能的算法是:
。。。或者,如果你想破解这些东西,所以它是正确的,我会开始看
部分原因是,这显然是错误的
# 5 楼答案
以下是Java中二进制搜索树的完整实现 插入、搜索、countNodes、遍历、删除、清空、最大值&;最小节点、查找父节点、打印所有叶节点、获取标高、获取高度、获取深度、打印左视图、镜像视图
# 6 楼答案
根据我对二进制搜索树的理解,下面的实现已经完成,敬请关注 并让我知道任何需要的反馈
请看一下主要的方法。因此,请提供您的反馈,以便我方进一步改进