右子树的高度比左子树的高度要高的时候进行左旋转java
左旋转的目的是为了下降右子树的高度node
左子树的高度比右子树的高度要高的时候进行右旋转web
右旋转的目的是为了下降左子树的高度ide
这个明显经过单个方向的旋转解决不了问题,须要使用双旋转
svg
package com.qin.avl; //平衡二叉树 public class AVLTreeDemo { public static void main(String[] args) { int[] arr = { 10,11,7,6,8,9}; //建立一个AVLTree对象 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("在旋转以后"); System.out.println("树的高度"+avlTree.getRoot().height()); System.out.println("树的左子树高度"+avlTree.getRoot().leftHeight()); System.out.println("树的右子树高度"+avlTree.getRoot().rightHeight()); } } //建立AVL Tree class AVLTree{ private Node root; public Node getRoot() { return root; } //添加节点的方法 public void add(Node node){ if (root==null){ root = node; //若是root为空,则直接让root指向node }else { root.add(node); } } //中序遍历 public void infixOrder(){ if (root!=null){ root.infixOrder(); }else { System.out.println("当前二叉排序树是空的,没法遍历"); } } } //建立node节点 class Node{ int value; Node left; Node right; public Node(int value) { this.value = value; } @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); } } //当添加完一个节点后,右子树的高度-左子树的高度的绝对值大于1 ,左旋转 if (rightHeight()-leftHeight()>1){ //若是他的右子树的左子树的高度大于它的右子树的高度 if (right!=null && right.left.height()>right.height()){ //对当前节点的右节点进行右旋转 right.rightRotate(); //在对当前节点进行左旋转 leftRotate(); }else { //否者对当前节点直接左旋转便可 leftRotate(); //左旋转 } return; //必需要!!! } if (leftHeight()-rightHeight()>1){ //右旋转 //若是他的左子树的右子树的高度大于他的左子树的高度 if (left!=null && left.right.height()>left.leftHeight()){ //先对当前节点的左节点(左子树)进行左旋转 left.leftRotate(); //在对当前节点进行右旋转 rightRotate(); }else { //不知足条件,直接右旋转便可 rightRotate(); } } } //中序遍历 public void infixOrder(){ if (this.left!=null){ this.left.infixOrder(); } System.out.println(this); if (this.right!=null){ this.right.infixOrder(); } } //返回以该节点为根节点,这颗树的高度 public int height(){ return Math.max(left==null?0:left.height(),right==null?0:right.height())+1; } //返回左子树的高度 public int leftHeight(){ if (left==null){ return 0; } return left.height(); } //返回右子树的高度 public int rightHeight(){ if (right==null){ return 0; } return right.height(); } //左旋转的方法 private void leftRotate(){ //建立新的节点,以当前根节点的值 Node newNode = new Node(value); //把新的节点的左子树设置为当前节点的左子树 newNode.left = left; //把新的节点的右子树设置成当前节点的右子树的左子树 newNode.right = right.left; //把当前节点的值替换成右子节点的值 value = right.value; //把当前节点的右子树设置成当前节点右子树的右子树 right = right.right; //把当前节点的左子节点设置成新的节点 left = newNode; } //右旋转的方法 private void rightRotate(){ //建立新的节点,以当前根节点的值 Node newNode = new Node(value); //把新的节点的右子树设置为当前节点的右子树 newNode.right = right; //把新的节点的左子树设置成当前节点的左子树的右子树 newNode.left = left.right; //把当前节点的值替换为左子节点的值 value = left.value; //把当前节点的左子树设置成当前节点左子树的左子树 left = left.left; right = newNode; } }