二叉平衡树
二叉排序树可能出现的问题:左子树过高或右子树过高,为了解决这种情况采用二叉平衡树树
二叉平衡树:可以看成将二叉排序树高的一边子树“往上提了一下”,即将该边子树的第一个从上至下的第一个结点作为新的根节点
原来的根节点放到另一边补充矮的子树的高度了。
当然还有特殊情况:
如果当前结点的右子树的左子树的高度大于右子树的右子树高度,先对它的右子树进行右旋转,然后再对当前结点进行左旋转,或者左子树的左子树高度大于它的右子树高度,先对它的左子树进行左旋转,然后再对当前结点进行右旋转,即双边排序
其代码就是在二叉排序树的代码上加上了一些改进,贴上改进代码:
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 }