二叉排序树
基本介绍
二叉排序树:BST: (Binary Sort(Search) Tree), 对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大
- 特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点
类似于这样一组数据 (7, 3, 9, 1, 4, 8, 15, 2) ,依次加入后对应的二叉排序树应为:
添加节点
添加的思路较简单,从根节点开始遍历添加,如果值比当前节点小,则向左子节点递归添加,如果比当前节点大,则向右子节点递归添加;
删除节点
-
先找到需要删除的节点;
-
再找到需要删除的节点的父节点;
-
判断需要删除的节点是以下那种类型:
a. 删除叶子节点,判断待删除节点是其父节点的左孩子还是右孩子,然后让其令为空;
b. 删除只有一颗子树的节点(如删除值为1的节点),判断待删除节点是其父节点的左孩子还是右孩子,判断待删除节点的子树是其左孩子还是右孩子,让父节点指向待删除节点的子树指向待删除节点的子树;
c. 删除有两颗子树的节点(如删除值为3的节点),判断待删除节点是其父节点的左孩子还是右孩子,顺着待删除节点的右子树,找到一个值最小的节点(该值的大小最接近待删除节点的值),让父节点指向待删除节点的子树指向上一步找到的最小的节点;
d. 删除根节点(如删除值为7的节点),删除根结点的方法和删除有两个子树的方法相似,找到一个接近根节点值的节点,删除该节点,将该节点的值赋值给根节点即可;
代码实现
/**
*@ClassName BinarySortTreeTest
*@Description 二叉排序树 代码实现
**/
public class BinarySortTreeTest {
public static void main(String[] args) {
BinarySortTree sortTree = new BinarySortTree();
sortTree.add(new BSTNode(7));
sortTree.add(new BSTNode(3));
sortTree.add(new BSTNode(9));
sortTree.add(new BSTNode(4));
sortTree.add(new BSTNode(15));
sortTree.add(new BSTNode(8));
sortTree.add(new BSTNode(1));
sortTree.add(new BSTNode(2));
System.out.println("前序排列:");
sortTree.prePrint();
System.out.println("删除后:");
sortTree.delNode(2);
sortTree.prePrint();
}
}
/** 二叉排序树代码实现*/
class BinarySortTree {
BSTNode root;
/**
* @Description 每个节点的左子节点小于该节点,右子节点大于该节点
**/
public void add(BSTNode newNode) {
if (root == null) {
root = newNode;
return;
}
root.add(newNode);
}
/**
* @Author tangjian
* @Description 删除节点方法
* 思路:
* 1. 先找到需要删除的节点
* 2. 再找到需要删除的节点的父节点
* 3. 判断需要删除的节点是以下那种类型
* a. 叶子节点
* b. 有一个子节点的节点
* c. 有两个子节点的节点 两种方法 1.找到右子树中最左节点 2. 找到左子中的最右节点 找到后与targetNode设置为该节点
**/
public void delNode(int value) {
BSTNode targetNode = select(value);
if (targetNode == null) {
System.out.println("要删除节点不存在");
}
BSTNode parentNode = selectParent(targetNode.value);
if (targetNode.left == null && targetNode.right == null) { //删除叶子节点
if (parentNode.left == targetNode) {
parentNode.left = null;
return;
}
if (parentNode.right == targetNode) {
parentNode.right = null;
return;
}
return;
} else if (targetNode.left != null && targetNode.right != null) { //删除具有两个子节点的节点
//获取右子树最小子树
int rightMinValue = getRightMinNode(targetNode.right);
delNode(rightMinValue);
targetNode.value = rightMinValue;
return;
} else { //删除具有一个子节点的节点
if (targetNode.left != null && targetNode.right == null) {
if (parentNode == null) { //如果parent为null 说明此时只有两个节点删除的是root节点 那个此时直接将left变为root
root = targetNode.left;
return;
}
if (parentNode.left == targetNode) {
parentNode.left = targetNode.left;
return;
}
if (parentNode.right == targetNode) {
parentNode.right = targetNode.left;
return;
}
}
if (targetNode.right != null && targetNode.left == null) {
if (parentNode == null) { //如果parent为null 说明此时只有两个节点删除的是root节点 那个此时直接将left变为root
root = targetNode.right;
return;
}
if (parentNode.left == targetNode) {
parentNode.left = targetNode.right;
return;
}
if (parentNode.right == targetNode) {
parentNode.right = targetNode.right;
return;
}
}
}
}
public BSTNode select(int value) {
if (root == null) {
System.out.println("当前BST为null");
}
return root.select(value);
}
public BSTNode selectParent(int value) {
if (root == null) {
System.out.println("当期那BST为null");
return null;
}
if (root.value == value) {
return null;
}
return root.selectParent(value);
}
public int getRightMinNode(BSTNode targetNode) {
BSTNode temp = targetNode;
while (temp.left != null) {
temp = temp.left;
}
return temp.value;
}
public void prePrint() {
if (root == null) {
System.out.println("当前BST为null");
}
root.prePrint();
}
}
/** 二叉排序树node节点 */
class BSTNode {
int value;
BSTNode left;
BSTNode right;
public BSTNode(int value) {
this.value = value;
}
@Override
public String toString() {
return "BSTNode{" +
"value=" + value +
'}';
}
public void add(BSTNode newNode) {
if (this.value > newNode.value && this.left == null) {
this.left = newNode;
return;
}
if (this.value <= newNode.value && this.right == null) {
this.right = newNode;
return;
}
if (this.value > newNode.value && this.left != null) {
this.left.add(newNode);
}
if (this.value <= newNode.value && this.right != null) {
this.right.add(newNode);
}
}
public void prePrint() { //前序遍历打印
System.out.println(this); //先遍历当前自己
if (this.left != null) {
this.left.prePrint();
}
if (this.right != null) {
this.right.prePrint();
}
}
//查找节点
public BSTNode select(int value) {
if (this.value == value) {
return this;
}
if (this.value > value && this.left != null) {
return this.left.select(value);
}
if (this.value <= value && this.right != null) {
return this.right.select(value);
}
return null;
}
//查找某个节点的父节点
public BSTNode selectParent(int value) {
if (this.left != null && this.left.value == value) {
return this;
}
if (this.right != null && this.right.value == value) {
return this;
}
if (this.value > value && this.left != null) {
return this.left.selectParent(value);
}
if (this.value < value && this.right != null) {
return this.right.selectParent(value);
}
return null;
}
}