二叉平衡树

二叉排序树可能出现的问题:左子树过高或右子树过高,为了解决这种情况采用二叉平衡树树

二叉平衡树:可以看成将二叉排序树高的一边子树“往上提了一下”,即将该边子树的第一个从上至下的第一个结点作为新的根节点

原来的根节点放到另一边补充矮的子树的高度了。

当然还有特殊情况:

如果当前结点的右子树的左子树的高度大于右子树的右子树高度,先对它的右子树进行右旋转,然后再对当前结点进行左旋转,或者左子树的左子树高度大于它的右子树高度,先对它的左子树进行左旋转,然后再对当前结点进行右旋转,即双边排序

其代码就是在二叉排序树的代码上加上了一些改进,贴上改进代码:

  1  //左旋转
  2         public void leftRotate()
  3         {
  4             //创建一个新结点,值为当前根节点的值
  5             Node newNode = new Node(value);
  6             //把新的结点的左子树设置为当前结点的左子树
  7             newNode.left = left;
  8             //把新的结点的左子树设置为当前结点的左子树
  9             newNode.right = right.left;
 10             //当前结点的值替换成右子结点的值
 11             value = right.value;
 12             //把当前结点的右子树设置成当前结点的右子结点的右子结点(跳过去)
 13             right = right.right;
 14             //把当前结点的左子结点设置成新结点
 15             left = newNode;
 16         }
 17 
 18         //右旋转
 19         public void rightRotata()
 20         {
 21             //创建一个新结点,值为当前根节点的值
 22             Node newNode = new Node(value);
 23             //把新的结点的右子树设置为当前结点的右子树
 24             newNode.right = right;
 25             //把新的结点的左子树设置为当前结点的右子树
 26             newNode.left = left.right;
 27             //当前结点的值替换成左子结点的值
 28             value = left.value;
 29             //把当前结点的左子树设置成当前结点的左子结点的左子结点(跳过去)
 30             left = left.left;
 31             //把当前结点的右子结点设置成新结点
 32             right = newNode;
 33         }
 34 
 35   public void add(Node node)
 36         {
 37             if (node == null)
 38             {
 39                 return;
 40             }
 41             //判断传入的结点值和当前子树根结点的关系
 42             //当前结点的值大于传入的值
 43             if (node.value < this.value)
 44             {
 45                 //如果左子树为空
 46                 if (this.left == null)
 47                 {
 48                     this.left = node;
 49                 }
 50                 else
 51                 //如果左子树不为空
 52                 {
 53                     //向左递归
 54                     this.left.add(node);
 55                 }
 56             }
 57             else//传入的值大于等于当前结点的值
 58             {
 59                 //右子树为空
 60                 if (this.right == null)
 61                 {
 62                     this.right = node;
 63                 }
 64                 //右子树不为空
 65                 else
 66                 {
 67                     //向右递归
 68                     this.right.add(node);
 69                 }
 70             }
 71             //添加完一个结点后,(右子树高度-左子树高度)>1 左旋转
 72             if (rightHeight() - leftHeight() > 1)
 73             {
 74                 //如果当前结点的右子树的左子树的高度大于右子树的右子树高度
 75                 //先对它的右子树进行右旋转,然后再对当前结点进行左旋转
 76                 if (right != null&&right.leftHeight()>right.rightHeight())
 77                 {
 78                     //先对右子结点进行右旋转
 79                     right.rightRotata();
 80                     leftRotate();
 81                 }
 82                 else
 83                 {
 84                     leftRotate();
 85                 }
 86                 return;
 87             }
 88             //添加完一个结点后,(左子树高度 - 右子树高度)> 1 右旋转
 89             if (leftHeight() - rightHeight() > 1)
 90             {
 91                 //左子树的左子树高度大于它的右子树高度
 92                 if (left != null && left.rightHeight() > leftHeight())
 93                 {
 94                     //对当前结点的左节点进行左旋转
 95                     left.leftRotate();
 96                     //对当前结点进行右旋转
 97                     rightHeight();
 98                 }
 99                 else
100                 {
101                     //直接右旋转
102                     rightHeight();
103                 }
104             }
105         }
原文地址:https://www.cnblogs.com/TheLin/p/13939141.html