声明:感谢尚硅谷的公开资料
二叉排序树
package dataStructure.binarySortTree;
/**
* 二叉排序
*/
public class BinarySortTreeDemo {
public static void main(String[] args) {
int[] arr = {7, 3, 10, 12, 5, 1, 9, 2};
BinarySortTree binarySortTree = new BinarySortTree();
// 循环添加
for (int v : arr) {
binarySortTree.add(new Node(v));
}
// 删除前遍历
binarySortTree.infixOrder();// 1、3、5、7、9、10、12
// System.out.println("删除叶子结点");
// 删除叶子结点
// binarySortTree.delNode(12);
/*System.out.println("删除只有一颗子树的结点");
binarySortTree.delNode(1);*/
System.out.println("删除有两颗子树的结点");
binarySortTree.delNode(10);
// 删除后遍历
binarySortTree.infixOrder();
}
}
// 创建二叉排序树
class BinarySortTree {
private Node root;
// 查找要删除的结点
public Node search(int value) {
if (null == root) {
return null;
}
return root.search(value);
}
// 查找要删除的结点的父节点
public Node searchParent(int value) {
if (null == root) {
return null;
}
return root.searchParent(value);
}
/**
* @param node 传入的结点(当作二叉排序树的根结点)
* @return 返回以node为根结点的二叉排序树的最小结点的值
*/
public int delRightTreeMin(Node node) {
Node target = node;
while (null != target.left) {
// 循环查找左子结点,就会找到最小值
target = target.left;
}
// 这是target指向了最小结点
// 删除最小结点
delNode(target.value);
return target.value;
}
public int delLeftTreeMin(Node node) {
Node target = node;
while (null != target.right) {
// 循环查找左子结点,就会找到最小值
target = target.right;
}
// 这是target指向了最小结点
// 删除最小结点
delNode(target.value);
return target.value;
}
// 删除节点
public void delNode(int value) {
if (null == root) {
return;
}
// 先查找删除的结点
Node targerNode = search(value);
if (null == targerNode) {
// 没找到删除的结点
return;
}
// targerNode没有父结点时,这颗二叉排序树只有一个结点
if (null == root.left && null == root.right) {
root = null;
return;
}
// 查找targetNode的父结点
Node targetParent = searchParent(value);
if (null == targerNode.left && null == targerNode.right) {
// 如果删除的是叶子结点
// 判断targetNode是targetParent的左子结点还是右子结点
if (null != targetParent.left && targetParent.left.value == value) {
targetParent.left = null;
} else if (null != targetParent.right && targetParent.right.value == value) {
targetParent.right = null;
}
} else if (null != targerNode.left && null != targerNode.right) {
// 删除有两颗子树
// int minValue = delRightTreeMin(targerNode.right);
// targerNode.value = minValue;
int maxValue = delLeftTreeMin(targerNode.left);
targerNode.value = maxValue;
} else {
// 删除只有一颗子树
if (null != targerNode.left) {
if(null != targetParent){
// 如果待删除结点有左子结点
if (targetParent.left.value == value) {
// 如果待删除的点是其父结点的左子结点
targetParent.left = targerNode.left;
} else {
// 如果待删除的点是其父结点的右子结点
targetParent.right = targerNode.left;
}
}else{
root = targerNode.left;
}
} else {
if(null != targetParent){
// 如果待删除结点有右子结点
if (targetParent.left.value == value) {
// 如果待删除的点是其父结点的左子结点
targetParent.left = targerNode.right;
} else {
// 如果待删除的点是其父结点的右子结点
targetParent.right = targerNode.right;
}
}else{
root = targerNode.right;
}
}
}
}
// 添加结点的方法
public void add(Node node) {
if (null == root) {
// 空树状态
root = node;
} else {
root.add(node);
}
}
// 中序遍历的方法
public void infixOrder() {
if (null == root) {
System.out.println("二叉排序树为空,无法遍历");
return;
}
root.infixOrder();
}
}
// 创建结点
class Node {
int value;
Node left;
Node right;
public Node(int value) {
this.value = value;
}
// 查找要删除的结点
/**
* @param value 要删除的结点的值
* @return 返回该结点,否则为空
*/
public Node search(int value) {
if (value == this.value) {
// 找到该结点
return this;
} else if (value < this.value) {
if (null != this.left) {
return this.left.search(value);
} else {
// 左子树为空
return null;
}
} else {
if (null != this.right) {
return this.right.search(value);
} else {
// 右子树为空
return null;
}
}
}
// 查找待删除结点的父结点
/**
* @param value 待删除结点
* @return 返回待删除结点的父结点 否则为空
*/
public Node searchParent(int value) {
if ((null != this.left && this.left.value == value)
|| (null != this.right && this.right.value == value)) {
return this;
} else {
// 查找的值小于当前结点的值,并且当前结点的左子结点不为空
if (value < this.value && null != this.left) {
// 向左子树递归查找
return this.left.searchParent(value);
} else if (value >= this.value && null != this.right) {
// 向右子树递归查找
return this.right.searchParent(value);
} else {
// 没有找到父节点
return null;
}
}
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
// 添加结点方法
// 递归形式添加,满足二叉排序要求
public void add(Node node) {
if (null == node) {
return;
}
// 判断传入的结点的值和当前子树的根结点的值关系
if (node.value < this.value) {
// 当前左子结点为空
if (null == this.left) {
this.left = node;
} else {
// 递归向左子树添加
this.left.add(node);
}
} else {
// 当前右子结点为空
if (null == this.right) {
this.right = node;
} else {
// 递归向右子树添加
this.right.add(node);
}
}
}
// 中序遍历
public void infixOrder() {
if (null != this.left) {
this.left.infixOrder();
}
System.out.println(this);
if (null != this.right) {
this.right.infixOrder();
}
}
}
}
}
// 中序遍历
public void infixOrder() {
if (null != this.left) {
this.left.infixOrder();
}
System.out.println(this);
if (null != this.right) {
this.right.infixOrder();
}
}
}