概述
把握一个思想直接完虐二叉排序树
: 比较 无论是添加节点,查找节点 抑或是删除节点, 核心都是比较, 而这正是基于其特点设计的, 下面是二叉排序树的全家桶, 拿走不谢
代码
本代码包括了从创建一个二叉排序树 到 增删查节点 每个方法都有比较详细的注释, 如果由任何疑问欢迎下方评论
package blibli.demo.树.二叉排序树;
import blibli.demo.线性结构.Node;
public class TreeNode implements Comparable<TreeNode>{
//节点的权
int value;
//左右节点
TreeNode left;
TreeNode right;
public TreeNode(int value) {
this.value = value;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public void setRight(TreeNode right) {
this.right = right;
}
/**
* 插入一个节点
* @param node
*/
public void insert(TreeNode node) {
if(node == null) return;
int result = node.compareTo(this);
if(result < 0) {
if(this.left == null){
this.left = node;
} else {
this.left.insert(node);
}
} else if(result > 0) {
if(this.right == null){
this.right = node;
} else {
this.right.insert(node);
}
}
}
@Override
public int compareTo(TreeNode o) {
if(o == null) throw new NullPointerException("比较的节点为空!");
return this.value - o.value;
}
public void midShow(TreeNode node) {
if (node == null) return;
midShow(node.left);
System.out.print(node.value + " ");
midShow(node.right);
}
/**
* 查找节点
* @param value
* @param node
* @return
*/
public TreeNode search(int value) {
if (this.value == value) return this;
else {
if(this.value < value && this.right != null) {
return this.right.search(value);
} else if(this.value > value && this.left != null)
return this.left.search(value);
else
return null;
}
}
/**
* 删除节点:
* 1.删除叶节点
* 2.删除只有一个孩子的节点
* 3.删除具有两个孩子的节点
* @param value
*/
public void delete(int value) {
TreeNode target = search(value);
if (target == null)
return;
else {
//删除节点的父节点, 无论是下面哪种情况都需要判断删除的节点是其左节点还是右节点
TreeNode parent = searchParent(value);
//叶节点
if(target.left == null && target.right == null) {
if(parent.left.value == value)
parent.left = null;
else
parent.right = null;
//双子节点
} else if (target.left != null && target.right != null) {
//从右子树种找到最小节点(为了保证中序遍历顺序输出) 将其赋值给目标删除节点 然后删除最小节点
int min = deleteMin(target.right);
target.value = min;
//独子节点
}else {
if(target.left != null) {
if(parent.left != null && parent.left.value == target.value) {
parent.left = target.left;
} else if (parent.right != null && parent.right.value == target.value) {
parent.right = target.left;
}
} else {
if(parent.left != null && parent.left.value == target.value) {
parent.left = target.right;
} else if (parent.right != null && parent.right.value == target.value) {
parent.right = target.right;
}
}
}
}
}
private int deleteMin(TreeNode node) {
TreeNode target = node;
//因为右子树中最小的节点一定没有左儿子 否则他就不是最小
while(target.left != null)
target = target.left;
int min = target.value;
delete(min);
return min;
}
/**
* 找到目标节点父节点
* @param value2
* @return
*/
private TreeNode searchParent(int value) {
if (this.left != null && this.left.value == value || this.right != null && this.right.value == value) {
return this;
} else {
if (this.value < value && this.left != null) {
return this.right.searchParent(value);
} else if (this.value > value && this.right != null) {
return this.left.searchParent(value);
}
return null;
}
}
}
package blibli.demo.树.二叉排序树;
public class BinarySortTree {
TreeNode root;
public void insert(TreeNode node) {
if(root == null) root = node;
else root.insert(node);
}
public void midShow() {
if (root == null) return;
root.midShow(root);
}
public TreeNode search(int value) {
return root == null ? null : root.search(value) ;
}
public void delete(int value) {
if (root == null) return;
root.delete(value);
}
}
-
测试
public static void main(String[] args) { BinarySortTree tree = new BinarySortTree(); int[] arr = new int[] {9, 3, 7, 4, 10,1}; for (int i = 0; i < arr.length; i++) { tree.insert(new TreeNode(arr[i])); } tree.midShow(); TreeNode node = tree.search(4); System.out.println(node); System.out.println("删除节点........................."); tree.delete(7); tree.midShow(); }
这里为了方便理解 附一张草图
闲聊
排序树思想比较简单, 核心就是我刚才说的比较 所以我这里实现了一个比较器, 方便进行比较 其中最关键的就是二叉排序树的删除, 这个有点不好理解, 阅读时需要反复揣摩意图.
收工!