| 一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST) |
| |
| 左子树全部为空,从形式上看,更像一个单链表. |
| 插入速度没有影响 |
| 查询速度明显降低(因为需要依次比较), 不能发挥BST的优势,因为每次还需要比较左子树,其查询速度比单链表还慢 |
| 解决方案-平衡二叉树(AVL) |

| # 在BinarySortTreeDemo的基础上完善 |
| |
| |
| class AVLTree { |
| private Node root; |
| |
| public Node getRoot() { |
| return root; |
| } |
| |
| |
| public Node search(int value) { |
| if(root == null) { |
| return null; |
| } else { |
| return root.search(value); |
| } |
| } |
| |
| |
| public Node searchParent(int value) { |
| if(root == null) { |
| return null; |
| } else { |
| return root.searchParent(value); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| public int delRightTreeMin(Node node) { |
| Node target = node; |
| |
| while(target.left != null) { |
| target = target.left; |
| } |
| |
| |
| delNode(target.value); |
| return target.value; |
| } |
| |
| |
| public void delNode(int value) { |
| if(root == null) { |
| return; |
| }else { |
| |
| Node targetNode = search(value); |
| |
| if(targetNode == null) { |
| return; |
| } |
| |
| if(root.left == null && root.right == null) { |
| root = null; |
| return; |
| } |
| |
| Node parent = searchParent(value); |
| |
| if(targetNode.left == null && targetNode.right == null) { |
| |
| if(parent.left != null && parent.left.value == value) { |
| parent.left = null; |
| } else if (parent.right != null && parent.right.value == value) { |
| parent.right = null; |
| } |
| } else if (targetNode.left != null && targetNode.right != null) { |
| int minVal = delRightTreeMin(targetNode.right); |
| targetNode.value = minVal; |
| } else { |
| |
| if(targetNode.left != null) { |
| if(parent != null) { |
| |
| if(parent.left.value == value) { |
| parent.left = targetNode.left; |
| } else { |
| parent.right = targetNode.left; |
| } |
| } else { |
| root = targetNode.left; |
| } |
| } else { |
| if(parent != null) { |
| |
| if(parent.left.value == value) { |
| parent.left = targetNode.right; |
| } else { |
| parent.right = targetNode.right; |
| } |
| } else { |
| root = targetNode.right; |
| } |
| } |
| } |
| } |
| } |
| |
| |
| public void add(Node node) { |
| if(root == null) { |
| root = node; |
| } else { |
| root.add(node); |
| } |
| } |
| |
| |
| public void infixOrder() { |
| if(root != null) { |
| root.infixOrder(); |
| } else { |
| System.out.println("二叉排序树为空,不能遍历"); |
| } |
| } |
| |
| } |
| |
| |
| class Node { |
| int value; |
| Node left; |
| Node right; |
| |
| public Node(int value) { |
| this.value = value; |
| } |
| |
| |
| |
| |
| |
| |
| public Node search(int value) { |
| if(value == this.value) { |
| return this; |
| } else if(value < this.value) { |
| |
| if(this.left == null) { |
| return null; |
| } |
| return this.left.search(value); |
| } else { |
| if(this.right == null) { |
| return null; |
| } |
| return this.right.search(value); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| public Node searchParent(int value) { |
| |
| if((this.left != null && this.left.value == value) || |
| (this.right != null && this.right.value == value)) { |
| return this; |
| } else { |
| |
| if(value < this.value && this.left != null) { |
| return this.left.searchParent(value); |
| } else if (value >= this.value && this.right != null) { |
| return this.right.searchParent(value); |
| } else { |
| return null; |
| } |
| } |
| } |
| |
| @Override |
| public String toString() { |
| return "Node [value=" + value + "]"; |
| } |
| |
| |
| |
| public void add(Node node) { |
| if(node == null) { |
| return; |
| } |
| |
| if(node.value < this.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 void infixOrder() { |
| if(this.left != null) { |
| this.left.infixOrder(); |
| } |
| System.out.println(this); |
| if(this.right != null) { |
| this.right.infixOrder(); |
| } |
| } |
| |
| } |
| |
| public int leftHeight() { |
| if (left == null) { |
| return 0; |
| } |
| return left.height(); |
| } |
| |
| |
| public int rightHeight() { |
| if (right == null) { |
| return 0; |
| } |
| return right.height(); |
| } |
| |
| |
| public int height() { |
| return Math.max(left == null ? 0 : left.height(), right == null ? 0 : right.height()) + 1; |
| } |
| |
| # 测试 |
| public class AVLTreeDemo { |
| |
| public static void main(String[] args) { |
| int[] arr = {4,3,6,5,7,8}; |
| |
| AVLTree avlTree = new AVLTree(); |
| |
| for(int i=0; i < arr.length; i++) { |
| avlTree.add(new Node(arr[i])); |
| } |
| |
| |
| System.out.println("中序遍历"); |
| avlTree.infixOrder(); |
| |
| System.out.println("在平衡处理~~"); |
| System.out.println("树的高度=" + avlTree.getRoot().height()); |
| System.out.println("树的左子树高度=" + avlTree.getRoot().leftHeight()); |
| System.out.println("树的右子树高度=" + avlTree.getRoot().rightHeight()); |
| } |
| |
| } |
| |
| private void leftRotate() { |
| |
| Node newNode = new Node(value); |
| |
| newNode.left = left; |
| |
| newNode.right = right.left; |
| |
| value = right.value; |
| |
| right = right.right; |
| |
| left = newNode; |
| } |
| |
| |
| |
| public void add(Node node) { |
| if (node == null) { |
| return; |
| } |
| |
| if (node.value < this.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); |
| } |
| } |
| |
| if(rightHeight() - leftHeight() > 1) { |
| leftRotate(); |
| } |
| } |
- 右旋转

| |
| private void rightRotate() { |
| Node newNode = new Node(value); |
| newNode.right = right; |
| newNode.left = left.right; |
| value = left.value; |
| left = left.left; |
| right = newNode; |
| } |
| |
| |
| |
| public void add(Node node) { |
| if (node == null) { |
| return; |
| } |
| |
| if (node.value < this.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); |
| } |
| } |
| |
| if(rightHeight() - leftHeight() > 1) { |
| leftRotate(); |
| } |
| |
| if(leftHeight() - rightHeight() > 1) { |
| rightRotate(); |
| } |
| } |
- 双旋转

| |
| |
| public void add(Node node) { |
| if (node == null) { |
| return; |
| } |
| |
| if (node.value < this.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); |
| } |
| } |
| |
| if(rightHeight() - leftHeight() > 1) { |
| |
| if(right != null && right.leftHeight() > right.rightHeight()) { |
| |
| right.rightRotate(); |
| |
| leftRotate(); |
| } else { |
| |
| leftRotate(); |
| } |
| return ; |
| } |
| |
| if(leftHeight() - rightHeight() > 1) { |
| |
| if(left != null && left.rightHeight() > left.leftHeight()) { |
| |
| left.leftRotate(); |
| |
| rightRotate(); |
| } else { |
| |
| rightRotate(); |
| } |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南