1、基本介绍
二叉排序树的创建
二叉排序树的删除
2、应用实例
package tree;
public class BinarySortTreeDemo {
public static void main(String[] args) {
BinarySortTree binarySortTree = new BinarySortTree();
int arr[] = {7, 3, 2, 11, 10, 12, 5, 1, 9};
for (int temp : arr) {
binarySortTree.add(new SNode(temp));
}
System.out.print("删除节点前:");
binarySortTree.inOrderTraverse();
// 删除叶子节点
// binarySortTree.delSNode(2);
// binarySortTree.inOrderTraverse();
// 删除带一棵子树的非叶子节点
// binarySortTree.delSNode(1);
// binarySortTree.inOrderTraverse();
// 删除带两棵子树的非叶子节点
binarySortTree.delSNode(10);
System.out.print("删除节点后:");
binarySortTree.inOrderTraverse();
}
}
class BinarySortTree {
public SNode root;
// 添加节点
public void add(SNode SNode) {
if (this.root == null) { // 判断当前是否是空树,是的话直接赋给root
this.root = SNode;
} else {
this.root.add(SNode);
}
}
// 中序遍历
public void inOrderTraverse() {
if (this.root != null) {
this.root.inOrderTraverse();
System.out.println();
} else {
return;
}
}
// 删除节点
public void delSNode(int data) {
if (this.root == null) {
return;
} else {
this.root.delSNode(data);
}
}
// 查找待删节点
public SNode searchDelSNode(int data) {
if (this.root == null) {
return null;
} else {
return this.root.searchDelSNode(data);
}
}
// 查找待删节点的父结点
public SNode searchParentSNode(int data) {
if (this.root == null) {
return null;
} else {
return this.root.searchParentSNode(data);
}
}
public int searchRightMin(SNode SNode) {
if (this.root == null) {
return -1;
} else {
return this.root.searchRightMin(SNode);
}
}
public int searchLeftMax(SNode SNode) {
if (this.root == null) {
return -1;
} else {
return this.root.searchLeftMax(SNode);
}
}
}
class SNode {
public int data;
public SNode left;
public SNode right;
public SNode(int data) {
this.data = data;
this.left = null;
this.right = null;
}
// 添加节点
public void add(SNode SNode) {
if (SNode == null) {
return;
}
// 先判断大小,决定是放左子树还是右子树
if (SNode.data > this.data) {
// 要放右边的话,判断其右子树是否为空
if (this.right == null) {
this.right = SNode;
} else {
this.right.add(SNode);
}
// 要放左边的话,判断其左子树是否为空
} else {
if (this.left == null) {
this.left = SNode;
} else {
this.left.add(SNode);
}
}
}
// 中序遍历
public void inOrderTraverse() {
if (this.left != null) {
this.left.inOrderTraverse();
}
System.out.print(this.data + " ");
if (this.right != null) {
this.right.inOrderTraverse();;
}
}
public void delSNode(int data) {
SNode targetSNode = searchDelSNode(data);
SNode parentSNode = searchParentSNode(data);
if (targetSNode == null || parentSNode == null) {
return;
}
// 第一种情况:删除的是叶子节点
if (targetSNode.left == null && targetSNode.right == null) {
// 判断删除节点是父节点的左子节点还是右子结点,从而对应删除
if (parentSNode.left == targetSNode) {
parentSNode.left = null;
} else if (parentSNode.right == targetSNode) {
parentSNode.right = null;
}
// 第二种情况:删除的是只有一棵子树的非叶子节点
} else if ((targetSNode.left == null && targetSNode.right != null) ||
(targetSNode.left != null && targetSNode.right == null)) {
// 先判断删除节点有左子树还是右子树
// 有左子树
if (targetSNode.left != null) {
// 再判断它是父节点的左子节点还是右子节点
if (targetSNode == parentSNode.left) {
parentSNode.left = targetSNode.left;
} else if (targetSNode == parentSNode.right) {
parentSNode.right = targetSNode.left;
}
// 右子树
} else if (targetSNode.right != null) {
// 再判断它是父节点的左子节点还是右子节点
if (targetSNode == parentSNode.left) {
parentSNode.left = targetSNode.right;
} else if (targetSNode == parentSNode.right){
parentSNode.right = targetSNode.right;
}
}
// 第三种情况:删除的是有两棵子树的非叶子节点
} else if (targetSNode.left != null && targetSNode.right != null) {
// 无需判断删除节点是父节点的左子树还是右子树
// 只需找到删除节点的右子树的最小节点 或者 找到删除节点的左子树的最大节点
// int temp = searchRightMin(targetSNode.right);
int temp = searchLeftMax(targetSNode.left);
targetSNode.data = temp;
}
}
public SNode searchDelSNode(int data) {
if (this.data == data) {
return this;
} else if (data <= this.data) {
if (this.left != null) {
return this.left.searchDelSNode(data);
}
} else {
if (this.right != null) {
return this.right.searchDelSNode(data);
}
}
return null;
}
public SNode searchParentSNode(int data) {
if ((this.left != null && this.left.data == data) ||
(this.right != null && this.right.data == data)) {
return this;
} else {
if (this.left != null && data < this.data) {
return this.left.searchParentSNode(data);
}else if (this.right != null && data > this.data) {
return this.right.searchParentSNode(data);
} else {
return null;
}
}
}
public int searchRightMin(SNode SNode) {
// 找该节点所在子树的最小值(根据二叉排序树特点,一般在最左边)
SNode temp = SNode;
while (temp.left != null) {
temp = temp.left;
}
delSNode(temp.data); // 删除该最小子结点
return temp.data;
}
public int searchLeftMax(SNode SNode) {
// 找该节点所在子树的最大值(根据二叉排序树特点,一般在最右边)
SNode temp = SNode;
while (temp.right != null) {
temp = temp.right;
}
delSNode(temp.data); // 删除该最小子结点
return temp.data;
}
@Override
public String toString() {
return "SNode[data=" + this.data + "]";
}
}