BST二叉排序树:又称二叉查找树,它是一种对排序和查找都很有用的特殊二叉树;满足data.key > lchild.key > data.key,即节点值大于左子树值小于右子树值;
BST二叉排序树很多高级数据结构和算法的基础,比如AVL平衡二叉树、Red-Black红黑树...
以下demo基本包含了BST二叉排序树的添加、删除、查找、前序遍历(递归和非递归)、中序遍历(递归和非递归)、后续遍历(递归和非递归)、按层级从上到下遍历...方法:
demo中用到的测试用例数据
节点类 TreeNode.java
/**
* @Author: ltx
* @Description: BST二叉树节点
*/
public class TreeNode {
public Integer value;//节点值
public TreeNode left;//左子节点
public TreeNode right;//右子节点
public TreeNode(Integer value) {
this.value = value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
BST二叉排序树类 BinarySortTree.java
/**
* @Author: ltx
* @Description:
*/
public class BinarySortTree {
public TreeNode root;//根节点;
/**
* 初始化BST树
*
* @param arr 树的元素
* @return
*/
public static BinarySortTree initBSTTree(int[] arr) {
BinarySortTree binarySortTree = new BinarySortTree();
for (int value : arr) {
binarySortTree.addBSTNode(new TreeNode(value));
}
return binarySortTree;
}
/**
* 前序
*/
public void preOrder(TreeNode node) {
System.out.print(node + ", ");
if (node.left != null) {
preOrder(node.left);
}
if (node.right != null) {
preOrder(node.right);
}
}
/**
* 前序-非递归实现
*/
public void preOrderNoRecursion(TreeNode node) {
Stack<TreeNode> st = new Stack<>();
TreeNode temp = node;
st.push(temp);
while (!st.isEmpty()) {
temp = st.pop();
if (temp.right != null) {
st.push(temp.right);
}
if (temp.left != null) {
st.push(temp.left);
}
System.out.print(temp + ", ");
}
}
/**
* 中序
*/
public void midOrder(TreeNode node) {
if (node.left != null) {
midOrder(node.left);
}
System.out.print(node + ", ");
if (node.right != null) {
midOrder(node.right);
}
}
/**
* 中序-非递归实现
*/
public void midOrderNoRecursion(TreeNode node) {
Stack<TreeNode> st = new Stack<>();
TreeNode temp = node;
while (temp != null || !st.isEmpty()) {
//一直往左边遍历走到底放栈中
while (temp != null) {
st.push(temp);
temp = temp.left;
}
//左边到底之后打印当前栈顶元素,再往右边走一下
if (!st.isEmpty()) {
//出栈
temp = st.pop();
System.out.print(temp + ", ");
//往右走
temp = temp.right;
}
}
}
/**
* 后序
*/
public void postOrder(TreeNode node) {
if (node.left != null) {
postOrder(node.left);
}
if (node.right != null) {
postOrder(node.right);
}
System.out.print(node + ", ");
}
/**
* 后序-非递归实现
* 原理-逆后续遍历,基于前序遍历调转左右子节点,当前->右->左,然后再反转,
*/
public void postOrderNoRecursion(TreeNode node) {
Stack<TreeNode> st1 = new Stack<>();
Stack<TreeNode> st2 = new Stack<>();
TreeNode temp = node;
st1.push(temp);
while (!st1.isEmpty()) {
temp = st1.pop();
if (temp.left != null) {
st1.push(temp.left);
}
if (temp.right != null) {
st1.push(temp.right);
}
st2.push(temp);
}
while (!st2.isEmpty()) {
System.out.print(st2.pop() + ", ");
}
}
/**
* 按层级从上到下遍历
* 原理:利用队列,类似图的广度优先遍历
*/
public void tierTraverse(TreeNode node) {
Queue<TreeNode> ls = new LinkedList();
ls.add(node);
while (!ls.isEmpty()) {
TreeNode temp = ls.remove();
if (temp.left != null) {
ls.add(temp.left);
}
if (temp.right != null) {
ls.add(temp.right);
}
System.out.print(temp + ", ");
}
}
/**
* 添加元素-BST树添加节点
*
* @param node 添加元素的节点
* @param element 要添加的节点
* @return
*/
public TreeNode addBSTNode(TreeNode node, TreeNode element) {
//root节点为空,则直接返回要添加的节点
if (node == null) {
return element;
}
if (element.value < node.value) {
if (node.left == null) {
node.left = element;
} else {
//递归回溯赋值
node.left = addBSTNode(node.left, element);
}
} else {
//右边空切值大于等于节点
if (node.right == null) {
node.right = element;
} else {
//递归回溯赋值
node.right = addBSTNode(node.right, element);
}
}
return node;
}
/**
* 查找
*
* @param value 要查找的节点值
* @param node 从哪个节点开始找, 一般是root节点
* @return
*/
public TreeNode search(Integer value, TreeNode node) {
if (node == null) {
System.out.println("未找到!");
return null;
}
if (node.value.equals(value)) {
System.out.println("找到: " + node);
return node;
}
if (value < node.value) {
if (node.left != null) {
//继续从左边找
return search(value, node.left);
} else {
System.out.println("未找到!");
return null;
}
} else {
if (node.right != null) {
//继续从右边找
return search(value, node.right);
} else {
System.out.println("未找到!");
return null;
}
}
}
/**
* node节点的树高
*
* @param node 节点
* @return
*/
public int getHeight(TreeNode node) {
int leftHeight = 0;
if (node.left != null) {
leftHeight = getHeight(node.left);
}
int rightHeight = 0;
if (node.right != null) {
rightHeight = getHeight(node.right);
}
return Math.max(leftHeight, rightHeight) + 1;
}
/**
* BST删除节点
*
* @param value 要查找的节点值
* @param node 节点
* @param parentNode 要查找节点的父节点(顺便获取查找节点父节点, 方便删除节点使用)
* @return
*/
public TreeNode deleteBSTNode(Integer value, TreeNode node, TreeNode parentNode) {
if (node.value.equals(value)) {
System.out.printf("找到, targetNode: %s, parentNode: %s\n", node, parentNode);
//这里返回的是被删除节点的位置
return deleteNode(node, parentNode);
}
if (value < node.value) {
if (node.left != null) {
//这里的node是父节点
node.left = deleteBSTNode(value, node.left, node);
} else {
System.out.println("未找到!");
return null;
}
} else {
if (node.right != null) {
//这里的node是父节点
node.right = deleteBSTNode(value, node.right, node);
} else {
System.out.println("未找到!");
return null;
}
}
return node;
}
/**
* 删除节点
* 首先找到删除节点 targetNode 和它的父节点 parentNode
* 节点的3中情况处理:
* 1.targetNode是叶子节点;
* if targetNode是parentNode的左子节点, 则 parentNode.left = null;
* if targetNode是parentNode的右子节点, 则 parentNode.right = null;
* 2.targetNode有1颗子树
* if targetNode有左子树,targetNode是parentNode的左子节点, 则 parentNode.left = targetNode.left;
* if targetNode有右子树,targetNode是parentNode的左子节点, 则 parentNode.left = targetNode.right;
* if targetNode有左子树,targetNode是parentNode的右子节点, 则 parentNode.right = targetNode.left;
* if targetNode有右子树,targetNode是parentNode的右子节点, 则 parentNode.right = targetNode.right;
* 3.targetNode有2颗子树;
* 左子树的最大节点(或者右子树中最小的节点) maxNode;
* 删除maxNode;
* (简单的对象,可以用 targetNode.value=maxNode.value 直接替代下面4步)
* maxNode.left = targetNode.left;
* maxNode.right = targetNode.right;
* if targetNode是parentNode的左子节点, 则 parentNode.left = maxNode;
* if targetNode是parentNode的右子节点, 则 parentNode.right = maxNode;
*
* @param targetNode 删除目标节点
* @param parentNode 删除目标节点的父节点
* @return 注意:这里返回的是被删除节点的位置
*/
public TreeNode deleteNode(TreeNode targetNode, TreeNode parentNode) {
if (targetNode == null) {
//没有找到要删除的节点直接返回false
System.out.println("没有找到要删除的节点...");
}
System.out.printf("targetNode: %s, parentNode: %s\n", targetNode, parentNode);
/**
* 1.targetNode是叶子节点;
*/
if (targetNode.left == null && targetNode.right == null) {
if (parentNode.left != null && parentNode.left.value.equals(targetNode.value)) {
//targetNode在左
parentNode.left = null;
} else if (parentNode.right != null && parentNode.right.value.equals(targetNode.value)) {
//targetNode在右
parentNode.right = null;
}
return null;
} else if (targetNode.left != null || targetNode.right != null) {
/**
* 2.targetNode有1颗子树
*/
if (targetNode.left != null && targetNode.right == null) {
//targetNode有1个左子树
if (parentNode.left != null && parentNode.left.value.equals(targetNode.value)) {
//targetNode在左
parentNode.left = targetNode.left;
} else if (parentNode.right != null && parentNode.right.value.equals(targetNode.value)) {
//targetNode在右
parentNode.right = targetNode.left;
}
return targetNode.left;
} else if (targetNode.right != null && targetNode.left == null) {
//targetNode有1个右子树
if (parentNode.left != null && parentNode.left.value.equals(targetNode.value)) {
//targetNode在parentNode左
parentNode.left = targetNode.right;
} else if (parentNode.right != null && parentNode.right.value.equals(targetNode.value)) {
//targetNode在parentNode右
parentNode.right = targetNode.right;
}
return targetNode.right;
} else if (targetNode.left != null && targetNode.right != null) {
/**
* 3.targetNode有2颗子树;
*/
//删除左边最大节点并返回
TreeNode maxNode = deleteMaxNode(targetNode.left, targetNode);
//最大节点值赋值到当前节点位置
targetNode.value = maxNode.value;
return targetNode;
}
}
return null;
}
/**
* 删除树最大节点
* 最大节点-一直往右边找。最右边的节点就是该树的最大节点
*
* @param
* @return maxNode
*/
public TreeNode deleteMaxNode(TreeNode temp, TreeNode parentNode) {
while (temp.right != null) {
parentNode = temp;
temp = temp.right;
}
//右子树中最大的节点 maxNode
TreeNode maxNode = temp;
//删除最大节点
deleteBSTNode(maxNode.value, maxNode, parentNode);
return maxNode;
}
/**
* BST添加元素
*
* @param node
*/
public void addBSTNode(TreeNode node) {
root = addBSTNode(root, node);
}
/**
* 遍历tree
*/
public void show() {
if (root != null) {
System.out.println("前序:");
preOrder(root);
System.out.println();
System.out.println("前序(非递归):");
preOrderNoRecursion(root);
System.out.println();
System.out.println("中序:");
midOrder(root);
System.out.println();
System.out.println("中序(非递归):");
midOrderNoRecursion(root);
System.out.println();
System.out.println("后序:");
postOrder(root);
System.out.println();
System.out.println("后序(非递归):");
postOrderNoRecursion(root);
System.out.println();
System.out.println("按层级从上到下遍历:");
tierTraverse(root);
System.out.println();
} else {
System.out.println("树为null");
}
}
/**
* 查找元素
*
* @param value
* @return
*/
public TreeNode search(Integer value) {
return search(value, root);
}
/**
* BST删除元素
*
* @param value
* @return
*/
public Boolean deleteBSTNode(Integer value) {
root = deleteBSTNode(value, root, null);
return true;
}
public static void main(String[] args) {
//初始化一个树
int[] arr = {7, 3, 8, 10, 12, 5, 1, 9, 2, 6, 4};
BinarySortTree binarySortTree = BinarySortTree.initBSTTree(arr);
//前中后序遍历节点
// binarySortTree.show();
// System.out.println("搜索: ");
// binarySortTree.search(9);
// System.out.println("树高: ");
// System.out.println(binarySortTree.getHeight(binarySortTree.root));
System.out.println("中序:");
binarySortTree.midOrder(binarySortTree.root);
System.out.println();
System.out.println("删除节点: ");
// binarySortTree.deleteAVLNode(9);
binarySortTree.deleteBSTNode(8);
// binarySortTree.deleteBSTNode(3);
// binarySortTree.deleteNode(2);
System.out.println("中序:");
binarySortTree.midOrder(binarySortTree.root);
System.out.println();
}
}