基本介绍:
- 二叉排序树BST(Binary Sort(Search) Tree),对于二叉排序树的任何一个非叶子节点要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。
- 特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点,如果二叉排序树中存在节点值相同的时候,示例代码中给出的获取节点的方法,只会返回第一个相同值的节点,这就致使在进行删除操作的时候会报栈溢出(StackOverflowError),所以,二叉排序中尽量避免值相同的情况
针对数组{7,3,10,12,5,1,9}对应的排序二叉树如下:

- BST添加(添加逻辑详见示例代码)完成后,通过中序遍历一定是有序的。
- BST的删除操作较复杂,逻辑如下:

示例代码
public class BinarySortTreeDemo {
public static void main(String[] args) {
int[] arr = {8, 4, 5, 7, 3, 33, 18, 16,4};
BinarySortTree binarySortTree = new BinarySortTree();
for (int item : arr) {
binarySortTree.addNode(new Node(item));
}
binarySortTree.infixOrder();
Node node = binarySortTree.get(10);
System.out.println("查找的节点:" + node);
node = binarySortTree.getParent(56);
System.out.println("查找节点的父节点:" + node);
for (int item : arr) {
binarySortTree.delNode(item);
}
System.out.println("删除节点后:");
binarySortTree.infixOrder();
}
}
@Data
class BinarySortTree {
private Node root;
public void infixOrder() {
if (root == null) {
System.out.println("空树,无法进行遍历");
} else {
root.infixOrder();
}
}
public void addNode(Node node) {
if (node == null) {
return;
}
if (root == null) {
root = node;
} else {
root.add(node);
}
}
public Node get(int value) {
if (root == null) {
return null;
}
return root.get(value);
}
public Node getParent(int value) {
if (root == null) {
return null;
}
return root.getParent(value);
}
public void delNode(int value) {
if (root == null) {
return;
}
Node targetNode = get(value);
if (targetNode == null) {
return;
}
if (root.getLeft() == null && root.getRight() == null) {
root = null;
return;
}
Node parent = getParent(value);
if (targetNode.getLeft() == null && targetNode.getRight() == null) {
if (parent.getLeft() != null && parent.getLeft().getValue() == value) {
parent.setLeft(null);
} else if (parent.getRight() != null && parent.getRight().getValue() == value) {
parent.setRight(null);
}
} else if (targetNode.getLeft() != null && targetNode.getRight() != null) {
int min = delRightTreeMin(targetNode.getRight());
targetNode.setValue(min);
} else {
if (targetNode.getLeft() != null) {
if (parent == null) {
root = targetNode.getLeft();
} else {
if (parent.getLeft() != null && parent.getLeft().getValue() == value) {
parent.setLeft(targetNode.getLeft());
} else if (parent.getRight() != null && parent.getRight().getValue() == value) {
parent.setRight(targetNode.getLeft());
}
}
} else {
if (parent == null) {
root = targetNode.getRight();
} else {
if (parent.getLeft() != null && parent.getLeft().getValue() == value) {
parent.setLeft(targetNode.getRight());
} else if (parent.getRight() != null && parent.getRight().getValue() == value) {
parent.setRight(targetNode.getRight());
}
}
}
}
}
public int delRightTreeMin(Node node) {
if (node == null) {
throw new RuntimeException("节点不能为空!");
}
Node targetNode = node;
while (targetNode.getLeft() != null) {
targetNode = targetNode.getLeft();
}
delNode(targetNode.getValue());
return targetNode.getValue();
}
public int delLeftTreeMax(Node node) {
if (node == null) {
throw new RuntimeException("节点不能为空!");
}
Node targetNode = node;
while (targetNode.getRight() != null) {
targetNode = targetNode.getRight();
}
delNode(targetNode.getValue());
return targetNode.getValue();
}
}
@Data
class Node {
private int value;
private Node left;
private Node right;
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
public void infixOrder() {
if (this.left != null) {
this.left.infixOrder();
}
System.out.println(this);
if (this.right != null) {
this.right.infixOrder();
}
}
public void add(Node node) {
if (node.value < 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 Node get(int value) {
if (this.value == value) {
return this;
}
if (value < this.value) {
if (this.left == null) {
return null;
}
return this.left.get(value);
} else {
if (this.right == null) {
return null;
}
return this.right.get(value);
}
}
public Node getParent(int value) {
if ((this.left != null && this.left.value == value) ||
(this.right != null && this.right.value == value)) {
return this;
}
if (value < this.value && this.left != null) {
return this.left.getParent(value);
}
if (value >= this.value && this.right != null) {
return this.right.getParent(value);
}
return null;
}
}