写在前面
二叉排序树
- 任何一个非叶子节点,左子节点比当前节点小,右子节点的值比当前节点大
- 右边的数都比左边大
- 对二叉排序树,进行
中序遍历
就是升序输出的
创建和添加
class BinarySortTree {
private Node root;
public void add(Node node) {
if (root == null) {
root = node;
} else {
root.add(node);
}
}
public void infixOrder() {
if (root != null) {
root.infixOrder();
} else {
System.out.println("empty");
}
}
}
class Node {
int value;
Node left;
Node right;
public void add(Node node) {
if (node == null) {
return;
}
if (node.value < this.value) {
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);
}
}
}
public void infixOrder() {
if (this.left != null) {
this.left.infixOrder();
}
System.out.println(this);
if (this.right != null) {
this.right.infixOrder();
}
}
}
删除
- 删除叶子节点
- 删除只有一颗子树的节点
- 删除有两棵子树的节点
节点方法
public Node search(int value) {
if (value == this.value) {
return this;
} else if (value < this.value) {
if (this.left == null) {
return null;
}
return this.left.search(value);
} else {
if (this.right == null) {
return null;
}
return this.right.search(value);
}
}
- 查找要删除节点的父节点,默认要删除的节点不是root,root在树中处理
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;
}
}
}
树方法
public Node search(int value) {
if (root == null) {
return null;
} else {
if (root.value == value) {
return root;
}
return root.search(value);
}
}
public Node searchParent(int value) {
if (root == null) {
return null;
} else {
if (root.value == value) {
return null;
}
return root.searchParent(value);
}
}
public void delNode(int value) {
if (root == null) {
return
} else {
Node targetNode = search(value)
if (targetNode == null) {
return
}
//找到targetNode的父节点
Node parent = searchParent(value)
//说明找到了root
if (parent == null) {
//如果当前只有一个节点,找到了要删除的节点,而且当前节点还只有一个节点,那么就是根节点
if (root.left == null && root.right == null) {
root = null
return
} else if (root.left != null && root.right == null) {
//如果只有左边有
root = root.left
return
}
else if (root.left == null && root.right != null) {
root = root.right
return
}
//两边都有,跟第二种情况一致处理
}
//第一种情况,如果删除的节点是叶子节点
if (targetNode.left == null && targetNode.right == null) {
//判断targetNode是父节点的左子节点或者右子节点
if (parent.left != null && parent.left.value == value) {
parent.left = null
} else if (parent.right != null && parent.right.value == value) {
parent.right = null
}
} else if (targetNode.left != null && targetNode.right != null) {
//第三种情况,删除有两棵子树的节点
//在右子树中找最小的,一定是大于左子树的,可以作为新的父节点
int minValue = delRightTreeMin(targetNode.right)
targetNode.value = minValue
} else {
//第二种情况,删除一棵子树的节点
//而targetNode一定是parent的子节点,通过`parent.left != null`保护第一个判断
//如果不是左子节点,那么就一定是右子节点
if (targetNode.left != null) {
if (parent.left != null && parent.left.value == value) {
//要删除的节点是父节点的左子节点
parent.left = targetNode.left
} else {
//targetNode是parent的右子节点
parent.right = targetNode.left
}
} else {
//删除的节点有右子节点
if (parent.left != null && parent.left.value == value) {
parent.left = targetNode.right
} else {
//targetNode是parent的右子节点
parent.right = targetNode.right
}
}
}
}
}
- 针对第三种情况,找到右子树中最小的节点(往右子树的左子树一直找),并替代删除的节点的值
public int delRightTreeMin(Node node) {
Node target = node;
while (target.left != null) {
target = target.left;
}
delNode(target.value);
return target.value;
}
public int delLeftTreeMax(Node node) {
Node target = node
//循环查找最小节点
while (target.right != null) {
target = target.right
}
delNode(target.value)
return target.value
}