Skip to content

Commit 0b371fe

Browse files
committed
[Bug fix]
1.Fix the bug in LL,RR 2.Add conclusion and code for insert.
1 parent 38887f3 commit 0b371fe

File tree

2 files changed

+223
-15
lines changed

2 files changed

+223
-15
lines changed

Algorithm(4th_Edition)/Notes/Tree/平衡二叉树BalancedBinaryTree.md

+103-8
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,127 @@
1616
>高度是指当前结点到叶子结点的最长路径,如所有叶子结点的高度都为0。
1717
![height](https://i.imgur.com/dA8OWAs.png)
1818

19+
## 旋转
1920
* 左左单旋转(LL)情景①分析
21+
>左左指的是在结点的左结点的左结点加入元素,被称为LL,此时要通过向右旋转使树平衡。
22+
2023
![LL](https://i.imgur.com/kpMVlUs.png)
2124
```Java
22-
private AVLNode singleRotateLeft(AVLNode n){
25+
/**
26+
* @Description: LL插入造成不平衡,通过单次向右旋转重新平衡树。
27+
* @param n
28+
* @return
29+
*/
30+
private AVLNode singleRotateRight(AVLNode n){
2331
AVLNode left1 = n.left;
2432
n.left = left1.right;
2533
left1.right = n;
26-
left1.height = Math.max(left1.left.height, left1.right.height) + 1;
27-
n.height = Math.max(n.left.height, n.right.height) + 1;
34+
n.height = Math.max(height(n.left), height(n.right)) + 1;
35+
left1.height = Math.max(height(left1.left), n.height) + 1;
2836
return left1;
2937
}
3038
```
3139

3240
* 右右单旋转(RR)情景④分析
41+
>右右指的是在结点的右结点的右结点插入元素造成的不平衡,成为RR,此时需要通过向左旋转使树平衡。
3342
![RR](https://i.imgur.com/CkFlj4X.png)
3443
```Java
35-
private AVLNode singleRotateRight(AVLNode n){
44+
/**
45+
* @Description: RR插入造成不平衡,通过单次向左旋转重新平衡树。
46+
* @param n
47+
* @return
48+
*/
49+
private AVLNode singleRotateLeft(AVLNode n){
3650
AVLNode right1 = n.right;
37-
n.left = right1.left;
51+
n.right = right1.left;
3852
right1.left = n;
39-
right1.height = Math.max(right1.left.height, right1.right.height) + 1;
40-
n.height = Math.max(n.left.height, n.right.height) + 1;
53+
n.height = Math.max(height(n.left), height(n.right)) + 1;
54+
right1.height = Math.max(n.height, height(right1.right)) + 1;
4155
return right1;
4256
}
4357
```
4458

4559
* 平衡二叉树的双旋转算法与实现
4660
* 左右双旋转(LR)情景②分析
47-
![LR](https://i.imgur.com/926XxBS.png)
61+
>在左子树的右子树插入造成的不平衡,LR,需要两次旋转实现平衡。
62+
![LR](https://i.imgur.com/926XxBS.png)
63+
```Java
64+
/**
65+
* @Description: LR造成的不平衡,需要两次旋转。
66+
* @param n
67+
* @return
68+
*/
69+
private AVLNode doubleRotateLR(AVLNode n){
70+
n.left = singleRotateLeft(n.left);
71+
return singleRotateRight(n);
72+
}
73+
```
74+
75+
* 右左双旋转(RL)情景③分析
76+
>向右结点的左结点插入新的元素,RL,两次旋转实现平衡。
77+
![RL](https://i.imgur.com/oZwL15T.png)
78+
```Java
79+
/**
80+
* @Description: RL造成的不平衡,两次旋转。
81+
* @param n
82+
* @return
83+
*/
84+
private AVLNode doubleRotateRL(AVLNode n){
85+
n.right = singleRotateRight(n.right);
86+
return singleRotateLeft(n);
87+
}
88+
```
89+
90+
* 插入结点
91+
```Java
92+
public void insert(V v){
93+
if(null == v){
94+
throw new RuntimeException("Cannot insert null to AVLTree");
95+
}
96+
root = insert(v, root);
97+
}
98+
99+
/**
100+
* @Description: 向AVLTree中加入元素。
101+
* @param v
102+
*/
103+
private AVLNode insert(V v, AVLNode node){
104+
//当前节点已经为空,新建结点。
105+
if(null == node){
106+
node = new AVLNode(v);
107+
}else if (v.compareTo(node.v) < 0) {
108+
//L
109+
node.left = insert(v, node.left);
110+
//如果造成了不平衡
111+
if(height(node.left) - height(node.right) == 2){
112+
//判断是LL还是LR
113+
if(v.compareTo(node.left.v) < 0){
114+
//LL
115+
node = singleRotateRight(node);
116+
}else{
117+
//LR
118+
node = doubleRotateLR(node);
119+
}
120+
}
121+
}else if(v.compareTo(node.v) > 0){
122+
//R
123+
node.right = insert(v, node.right);
124+
//判断是否需要旋转
125+
if(height(node.right) - height(node.left) == 2){
126+
//判断LR/RR
127+
if(v.compareTo(node.right.v) > 0){
128+
//RR
129+
node = singleRotateLeft(node);
130+
}else{
131+
//RL
132+
node = doubleRotateRL(node);
133+
}
134+
}
135+
}else{
136+
//如果要插入的数据和当前遍历到数据一致,do nothing
137+
;
138+
}
139+
node.height = Math.max(height(node.left), height(node.right)) + 1;
140+
return node;
141+
}
142+
```

Algorithm(4th_Edition)/src/ca/mcmaster/chapter/three/bitree/BalancedBinaryTree.java

+120-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ca.mcmaster.chapter.three.bitree;
22

33
public class BalancedBinaryTree<V extends Comparable<V>> {
4+
private AVLNode root;
45
private class AVLNode{
56
V v;
67
int height; //当前节点的子树的高度
@@ -19,24 +20,136 @@ public AVLNode(V v) {
1920
}
2021
}
2122
private int height(AVLNode n){
23+
if(n == null) return -1;
2224
return n.height;
2325
}
2426

25-
private AVLNode singleRotateLeft(AVLNode n){
27+
/**
28+
* @Description: LL插入造成不平衡,通过单次向右旋转重新平衡树。
29+
* @param n
30+
* @return
31+
*/
32+
private AVLNode singleRotateRight(AVLNode n){
2633
AVLNode left1 = n.left;
2734
n.left = left1.right;
2835
left1.right = n;
29-
left1.height = Math.max(left1.left.height, left1.right.height) + 1;
30-
n.height = Math.max(n.left.height, n.right.height) + 1;
36+
n.height = Math.max(height(n.left), height(n.right)) + 1;
37+
left1.height = Math.max(height(left1.left), n.height) + 1;
3138
return left1;
3239
}
3340

34-
private AVLNode singleRotateRight(AVLNode n){
41+
/**
42+
* @Description: RR插入造成不平衡,通过单次向左旋转重新平衡树。
43+
* @param n
44+
* @return
45+
*/
46+
private AVLNode singleRotateLeft(AVLNode n){
3547
AVLNode right1 = n.right;
36-
n.left = right1.left;
48+
n.right = right1.left;
3749
right1.left = n;
38-
right1.height = Math.max(right1.left.height, right1.right.height) + 1;
39-
n.height = Math.max(n.left.height, n.right.height) + 1;
50+
n.height = Math.max(height(n.left), height(n.right)) + 1;
51+
right1.height = Math.max(n.height, height(right1.right)) + 1;
4052
return right1;
4153
}
54+
55+
/**
56+
* @Description: LR造成的不平衡,需要两次旋转。
57+
* @param n
58+
* @return
59+
*/
60+
private AVLNode doubleRotateLR(AVLNode n){
61+
n.left = singleRotateLeft(n.left);
62+
return singleRotateRight(n);
63+
}
64+
65+
/**
66+
* @Description: RL造成的不平衡,两次旋转。
67+
* @param n
68+
* @return
69+
*/
70+
private AVLNode doubleRotateRL(AVLNode n){
71+
n.right = singleRotateRight(n.right);
72+
return singleRotateLeft(n);
73+
}
74+
75+
public void insert(V v){
76+
if(null == v){
77+
throw new RuntimeException("Cannot insert null to AVLTree");
78+
}
79+
root = insert(v, root);
80+
}
81+
82+
/**
83+
* @Description: 向AVLTree中加入元素。
84+
* @param v
85+
*/
86+
private AVLNode insert(V v, AVLNode node){
87+
//当前节点已经为空,新建结点。
88+
if(null == node){
89+
node = new AVLNode(v);
90+
}else if (v.compareTo(node.v) < 0) {
91+
//L
92+
node.left = insert(v, node.left);
93+
//如果造成了不平衡
94+
if(height(node.left) - height(node.right) == 2){
95+
//判断是LL还是LR
96+
if(v.compareTo(node.left.v) < 0){
97+
//LL
98+
node = singleRotateRight(node);
99+
}else{
100+
//LR
101+
node = doubleRotateLR(node);
102+
}
103+
}
104+
}else if(v.compareTo(node.v) > 0){
105+
//R
106+
node.right = insert(v, node.right);
107+
//判断是否需要旋转
108+
if(height(node.right) - height(node.left) == 2){
109+
//判断LR/RR
110+
if(v.compareTo(node.right.v) > 0){
111+
//RR
112+
node = singleRotateLeft(node);
113+
}else{
114+
//RL
115+
node = doubleRotateRL(node);
116+
}
117+
}
118+
}else{
119+
//如果要插入的数据和当前遍历到数据一致,do nothing
120+
;
121+
}
122+
123+
node.height = Math.max(height(node.left), height(node.right)) + 1;
124+
return node;
125+
}
126+
127+
public static void main(String[] args) {
128+
BalancedBinaryTree<Integer> avlTree = new BalancedBinaryTree<>();
129+
avlTree.insert(5);
130+
System.out.println("insert :" + 5);
131+
System.out.println(avlTree.root.v);
132+
System.out.println(avlTree.height(avlTree.root));
133+
System.out.println("-------------------------------------");
134+
avlTree.insert(3);
135+
System.out.println("insert :" + 3);
136+
System.out.println(avlTree.root.v);
137+
System.out.println(avlTree.height(avlTree.root));
138+
System.out.println("-------------------------------------");
139+
avlTree.insert(4);
140+
System.out.println("insert :" + 4);
141+
System.out.println(avlTree.root.v);
142+
System.out.println(avlTree.height(avlTree.root));
143+
System.out.println("-------------------------------------");
144+
avlTree.insert(6);
145+
System.out.println("insert :" + 6);
146+
System.out.println(avlTree.root.v);
147+
System.out.println(avlTree.height(avlTree.root));
148+
System.out.println("-------------------------------------");
149+
avlTree.insert(7);
150+
System.out.println("insert :" + 7);
151+
System.out.println(avlTree.root.v);
152+
System.out.println(avlTree.height(avlTree.root));
153+
System.out.println("-------------------------------------");
154+
}
42155
}

0 commit comments

Comments
 (0)