@@ -3,6 +3,13 @@ import 'FileOperator.dart';
3
3
4
4
/**
5
5
* AVL树
6
+ * 第一个自平衡的树
7
+ *
8
+ * 添加,删除
9
+ * LL,RR,RL,LR
10
+ *
11
+ * 平衡二叉树
12
+ * 每个节点的左右子树高度相差1
6
13
*/
7
14
class AVLTree <K extends Comparable <K >, V > {
8
15
_Node ? root;
@@ -16,11 +23,10 @@ class AVLTree<K extends Comparable<K>, V> {
16
23
17
24
@override
18
25
add (key, value) {
19
- // TODO: implement add
20
26
root = _addNode (root, key, value);
21
27
}
22
28
23
- _Node _addNode (_Node ? node, K key, V value) {
29
+ _Node ? _addNode (_Node ? node, K key, V value) {
24
30
if (node == null ) {
25
31
size = size! + 1 ;
26
32
return new _Node (key, value);
@@ -39,42 +45,100 @@ class AVLTree<K extends Comparable<K>, V> {
39
45
1 + [_getHeight (node.left), _getHeight (node.right)].reduce (max);
40
46
// 计算平衡因子
41
47
int balanceFactor = getBalanceFactor (node);
42
- if (balanceFactor.abs () > 1 ) {
43
- // print("unbalanced: $balanceFactor");
48
+ if (balanceFactor> 1 && getBalanceFactor (node.left) >= 0 ) {
49
+ return _rightRotate (node);
50
+ }
51
+ //
52
+ if (balanceFactor < - 1 && getBalanceFactor (node.right) <= 0 ) {
53
+ return _leftRotate (node);
54
+ }
55
+
56
+ if (balanceFactor > 1 && getBalanceFactor (node.left) < 0 ) {
57
+ node.left = _leftRotate (node.left! );
58
+ return _rightRotate (node);
59
+ }
60
+
61
+ if (balanceFactor < - 1 && getBalanceFactor (node.right) > 0 ) {
62
+ node.right = _rightRotate (node.right! );
63
+ return _leftRotate (node);
44
64
}
45
65
return node;
46
66
}
47
67
68
+ // 对节点y进行向右旋转操作,返回旋转后新的根节点x
69
+ // y x
70
+ // / \ / \
71
+ // x T4 向右旋转 (y) z y
72
+ // / \ - - - - - - - -> / \ / \
73
+ // z T3 T1 T2 T3 T4
74
+ // / \
75
+ // T1 T2
76
+ _Node ? _rightRotate (_Node y) {
77
+ _Node ? x = y.left;
78
+ _Node ? T3 = x? .right;
79
+
80
+ // 向右旋转过程
81
+ x? .right = y;
82
+ y.left = T3 ;
83
+
84
+ // 更新height
85
+ y.height = [_getHeight (y.left), _getHeight (y.right)].reduce (max) + 1 ;
86
+ x? .height = [_getHeight (x.left), _getHeight (x.right)].reduce (max) + 1 ;
87
+
88
+ return x;
89
+ }
90
+
91
+ // 对节点y进行向左旋转操作,返回旋转后新的根节点x
92
+ // y x
93
+ // / \ / \
94
+ // T1 x 向左旋转 (y) y z
95
+ // / \ - - - - - - - -> / \ / \
96
+ // T2 z T1 T2 T3 T4
97
+ // / \
98
+ // T3 T4
99
+ _Node ? _leftRotate (_Node y) {
100
+ _Node ? x = y.right;
101
+ _Node ? T2 = x? .left;
102
+
103
+ // 向左旋转过程
104
+ x? .left = y;
105
+ y.right = T2 ;
106
+
107
+ // 更新height
108
+ y.height = [_getHeight (y.left), _getHeight (y.right)].reduce (max) + 1 ;
109
+ x? .height = [_getHeight (x.left), _getHeight (x.right)].reduce (max) + 1 ;
110
+
111
+ return x;
112
+ }
113
+
48
114
// 判断该二叉树是否是一棵平衡二叉树
49
- bool isBalanced (){
115
+ bool isBalanced () {
50
116
return _isBalancedDetail (root);
51
117
}
52
118
53
119
// 判断以Node为根的二叉树是否是一棵平衡二叉树,递归算法
54
- bool _isBalancedDetail (_Node ? node){
55
-
56
- if (node == null )
57
- return true ;
120
+ bool _isBalancedDetail (_Node ? node) {
121
+ if (node == null ) return true ;
58
122
59
123
int balanceFactor = getBalanceFactor (node);
60
- if (balanceFactor.abs () > 1 )
61
- return false ;
124
+ if (balanceFactor.abs () > 1 ) return false ;
62
125
return _isBalancedDetail (node.left) && _isBalancedDetail (node.right);
63
126
}
64
127
65
128
//获得节点node的平衡因子
66
- int getBalanceFactor (_Node node) {
67
- if (node == null ) return 0 ;
129
+ int getBalanceFactor (_Node ? node) {
130
+ if (node == null ) {
131
+ return 0 ;
132
+ }
68
133
return _getHeight (node.left) - _getHeight (node.right);
69
134
}
70
135
71
136
// 判断该二叉树是否是一棵二分搜索树
72
137
bool isBST () {
73
-
74
138
List keys = List .empty (growable: true );
75
139
_inOrder (root, keys);
76
- for (int i = 1 ; i < keys.length ; i ++ ) {
77
- if (keys[i- 1 ].compareTo (keys[i])> 0 ) {
140
+ for (int i = 1 ; i < keys.length; i++ ) {
141
+ if (keys[i - 1 ].compareTo (keys[i]) > 0 ) {
78
142
return false ;
79
143
}
80
144
}
@@ -145,36 +209,76 @@ class AVLTree<K extends Comparable<K>, V> {
145
209
if (node == null ) {
146
210
return null ;
147
211
}
212
+ _Node ? retNode;
148
213
if (key.compareTo (node._key) < 0 ) {
149
214
node.left = _removeNode (node.left! , key);
150
- return node;
215
+ // return node;
216
+ retNode = node;
151
217
} else if (key.compareTo (node._key) > 0 ) {
152
218
node.right = _removeNode (node.right! , key);
153
- return node;
219
+ // return node;
220
+ retNode = node;
154
221
} else {
155
222
// 待删除节点左子树为空的情况
156
223
if (node.left == null ) {
157
224
_Node ? rightNode = node.right;
158
225
node.right = null ;
159
226
size = size! - 1 ;
160
- return rightNode;
227
+ // return rightNode;
228
+ retNode = rightNode;
161
229
}
162
230
// 待删除节点右子树为空的情况
163
231
if (node.right == null ) {
164
232
_Node ? leftNode = node.left;
165
233
node.left = null ;
166
234
size = size! - 1 ;
167
- return leftNode;
235
+ // return leftNode;
236
+ retNode = leftNode;
168
237
}
169
238
// 待删除节点左右子树均不为空的情况
170
239
// 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
171
240
// 用这个节点顶替待删除节点的位置
172
241
_Node successor = _minimum (node.right! );
173
- successor.right = _removeMin (node.right! );
242
+ //w维持平衡性操作,不再执行removemin
243
+ successor.right = _removeNode (node.right! ,successor._key);
174
244
successor.left = node.left;
175
245
node.left = node.right = null ;
176
- return successor;
246
+ // return successor;
247
+ retNode = successor;
248
+ }
249
+ if (retNode == null ) {
250
+ return null ;
251
+ }
252
+
253
+ // 更新height
254
+ retNode.height = 1 + [_getHeight (retNode.left), _getHeight (retNode.right)].reduce (max);
255
+
256
+ // 计算平衡因子
257
+ int balanceFactor = getBalanceFactor (retNode);
258
+
259
+ // 平衡维护
260
+ // LL
261
+ if (balanceFactor > 1 && getBalanceFactor (retNode.left) >= 0 )
262
+ return _rightRotate (retNode);
263
+
264
+ // RR
265
+ if (balanceFactor < - 1 && getBalanceFactor (retNode.right) <= 0 )
266
+ return _leftRotate (retNode);
267
+
268
+ // LR
269
+ if (balanceFactor > 1 && getBalanceFactor (retNode.left) < 0 ) {
270
+ retNode.left = _leftRotate (retNode.left! );
271
+ return _rightRotate (retNode);
177
272
}
273
+
274
+ // RL
275
+ if (balanceFactor < - 1 && getBalanceFactor (retNode.right) > 0 ) {
276
+ retNode.right = _rightRotate (retNode.right! );
277
+ return _leftRotate (retNode);
278
+ }
279
+
280
+ return retNode;
281
+
178
282
}
179
283
180
284
// 删除掉以node为根的二分搜索树中的最小节点
0 commit comments