1.介绍:
2.二叉排序树的创建和遍历【遍历采用中序遍历】:
添加结点【在Node类中】:
然后在二叉排序树类中
class BinarySortTree 封装方法
public void add(Node node) {
if(node == null) {
return;
}
//判断传入的结点的值,和当前子树的根结点的值关系
if(node.value < this.value) {
//如果当前结点左子结点为null
if(this.left == null) {
this.left = node;
} else {
//递归的向左子树添加
this.left.add(node);
}
} else { //添加的结点的值大于 当前结点的值
if(this.right == null) {
this.right = node;
} else {
//递归的向右子树添加
this.right.add(node);
}
}
}
3.删除结点【下面两个方法全部封装到二叉排序树中】:
需要先写出两个方法 : 1. 找到目标结点 2.找到目标结点的父结点
1. 找到目标结点:
public Node search(int value) { if(value == this.value) //找到就是该结点 return this; else if(value < this.value) {//如果查找的值小于当前结点,向左子树递归查找 //如果左子结点为空 if(this.left == null) return null; else return this.left.search(value); } else { //如果查找的值不小于当前结点,向右子树递归查找 if(this.right == null) return null; else return this.right.search(value); } }
2.找到目标结点的父结点:
public Node searchParent(int value) { //如果当前结点就是要删除的结点的父结点,就返回 if((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value)) return this; else { //如果查找的值小于当前结点的值, 并且当前结点的左子结点不为空 if(value < this.value && this.left != null) return this.left.searchParent(value); //向左子树递归查找 else if (value >= this.value && this.right != null) return this.right.searchParent(value); //向右子树递归查找 else return null; // 没有找到父结点 } }
有三种情况:
(1)删除叶子结点【BinarySortTree类中】:
(2)删除只有一棵子树的结点
(3)删除有两棵子树的结点
public void delNode(int value) {
if(root == null)
return;
else {
//找目标结点
Node target = root.search(value);
if(target == null) {
System.out.println("找不到目标结点");
return;
}
//只有一个结点
else if (root.right == null && root.left == null) {
root = null;
return;
}
//找父结点
Node parent = searchParent(value);
//1.删除的是叶子结点
if (target.left == null && target.right == null) {
if (parent.left != null && parent.left.value == target
.value)
parent.left = null;
else if (parent.right != null && parent.right.value ==
target.value)
parent.right = null;
}
//2.删除只有一颗子树的结点
//2.1 假如target有左子树
if(target.left!=null&&target.right == null){
//target是父结点的左子树
if (parent != null) { // !!! 考虑父节点是否为空
if (parent.left != null && parent.left.value == value)
parent.left = target.left;
//target是父节点的右结点
if (parent.right != null && parent.right.value == value)
parent.right = target.left;
}
else root = target.left;
}
//2.2假如target有右子树
else if(target.right!=null&&target.left == null){
//target是父结点的左结点
if (parent != null) {
if (parent.left != null && parent.left.value == value)
parent.left = target.right;
//target是父节点的右结点
if (parent.right != null && parent.right.value == value)
parent.right = target.right;
}
else root = target.right;
}
//删除有两颗子树
//找到target的右子树最小结点
else if (target.left != null && target.right != null) {
int min = delRightTreeMin(target.right); //找到右子树最小左子结点并删除,然后返回该数
target.value = min; //直接赋给目标结点
}
}
}
//找到目标结点的右子树最小左子结点
public int delRightTreeMin(Node node) {
Node target = node; //target 临时变量
//循环的查找左子节点,就会找到最小值
while(target.left != null) {
target = target.left;
}
//这时 target就指向了最小结点
//删除最小结点
delNode(target.value);
return target.value;
}