Skip to content

Commit 7f1b62b

Browse files
author
tianqing.liang
committed
AVL树,红黑树
1 parent bcf0d9f commit 7f1b62b

File tree

9 files changed

+30415
-28
lines changed

9 files changed

+30415
-28
lines changed

19-AVL-Tree/AVLTree.dart

Lines changed: 126 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ import 'FileOperator.dart';
33

44
/**
55
* AVL树
6+
* 第一个自平衡的树
7+
*
8+
* 添加,删除
9+
* LL,RR,RL,LR
10+
*
11+
* 平衡二叉树
12+
* 每个节点的左右子树高度相差1
613
*/
714
class AVLTree<K extends Comparable<K>, V> {
815
_Node? root;
@@ -16,11 +23,10 @@ class AVLTree<K extends Comparable<K>, V> {
1623

1724
@override
1825
add(key, value) {
19-
// TODO: implement add
2026
root = _addNode(root, key, value);
2127
}
2228

23-
_Node _addNode(_Node? node, K key, V value) {
29+
_Node? _addNode(_Node? node, K key, V value) {
2430
if (node == null) {
2531
size = size! + 1;
2632
return new _Node(key, value);
@@ -39,42 +45,100 @@ class AVLTree<K extends Comparable<K>, V> {
3945
1 + [_getHeight(node.left), _getHeight(node.right)].reduce(max);
4046
// 计算平衡因子
4147
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);
4464
}
4565
return node;
4666
}
4767

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+
48114
// 判断该二叉树是否是一棵平衡二叉树
49-
bool isBalanced(){
115+
bool isBalanced() {
50116
return _isBalancedDetail(root);
51117
}
52118

53119
// 判断以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;
58122

59123
int balanceFactor = getBalanceFactor(node);
60-
if(balanceFactor.abs() > 1)
61-
return false;
124+
if (balanceFactor.abs() > 1) return false;
62125
return _isBalancedDetail(node.left) && _isBalancedDetail(node.right);
63126
}
64127

65128
//获得节点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+
}
68133
return _getHeight(node.left) - _getHeight(node.right);
69134
}
70135

71136
// 判断该二叉树是否是一棵二分搜索树
72137
bool isBST() {
73-
74138
List keys = List.empty(growable: true);
75139
_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) {
78142
return false;
79143
}
80144
}
@@ -145,36 +209,76 @@ class AVLTree<K extends Comparable<K>, V> {
145209
if (node == null) {
146210
return null;
147211
}
212+
_Node? retNode;
148213
if (key.compareTo(node._key) < 0) {
149214
node.left = _removeNode(node.left!, key);
150-
return node;
215+
// return node;
216+
retNode = node;
151217
} else if (key.compareTo(node._key) > 0) {
152218
node.right = _removeNode(node.right!, key);
153-
return node;
219+
// return node;
220+
retNode = node;
154221
} else {
155222
// 待删除节点左子树为空的情况
156223
if (node.left == null) {
157224
_Node? rightNode = node.right;
158225
node.right = null;
159226
size = size! - 1;
160-
return rightNode;
227+
// return rightNode;
228+
retNode = rightNode;
161229
}
162230
// 待删除节点右子树为空的情况
163231
if (node.right == null) {
164232
_Node? leftNode = node.left;
165233
node.left = null;
166234
size = size! - 1;
167-
return leftNode;
235+
// return leftNode;
236+
retNode = leftNode;
168237
}
169238
// 待删除节点左右子树均不为空的情况
170239
// 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
171240
// 用这个节点顶替待删除节点的位置
172241
_Node successor = _minimum(node.right!);
173-
successor.right = _removeMin(node.right!);
242+
//w维持平衡性操作,不再执行removemin
243+
successor.right = _removeNode(node.right!,successor._key);
174244
successor.left = node.left;
175245
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);
177272
}
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+
178282
}
179283

180284
// 删除掉以node为根的二分搜索树中的最小节点

19-AVL-Tree/BST.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ class BST<K extends Comparable<K>, V> {
1414
@override
1515
add(key, value) {
1616
// TODO: implement add
17-
root = _addNode(root!, key, value);
17+
root = _addNode(root, key, value);
1818
}
1919

20-
_Node _addNode(_Node node, K key, V value) {
20+
_Node _addNode(_Node? node, K key, V value) {
2121
if (node == null) {
2222
size = size! + 1;
2323
return _Node(key, value);
2424
}
2525

2626
if (key.compareTo(node._key) < 0) {
27-
node.left = _addNode(node.left!, key, value);
27+
node.left = _addNode(node.left, key, value);
2828
} else if (key.compareTo(node._key) > 0) {
29-
node.right = _addNode(node.right!, key, value);
29+
node.right = _addNode(node.right, key, value);
3030
} else {
3131
// key.compareTo(node.key) == 0
3232
node._value = value;
@@ -155,8 +155,6 @@ class _Node<K, V> {
155155

156156
_Node? left, right;
157157

158-
159-
160158
_Node(K key, V value) {
161159
this._key = key;
162160
this._value = value;

19-AVL-Tree/Main.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'FileOperator.dart';
2+
import 'BST.dart';
3+
import 'AVLTree.dart';
4+
5+
void main() async{
6+
7+
print("Pride and Prejudice");
8+
9+
List words = await FileOperator.getFileString('text2.txt');
10+
11+
// words.sort();
12+
13+
// Test BST
14+
var now = new DateTime.now();
15+
num startTime = now.millisecondsSinceEpoch;
16+
17+
BST<String, num> bst = BST();
18+
for (String word in words) {
19+
if (bst.contains(word))
20+
bst.set(word, bst.get(word) + 1);
21+
else
22+
bst.add(word, 1);
23+
}
24+
25+
for(String word in words)
26+
bst.contains(word);
27+
28+
var endNow = new DateTime.now();
29+
num endTime = endNow.millisecondsSinceEpoch;
30+
31+
double time = (endTime - startTime) / 1000.0;
32+
print("BST: $time s");
33+
34+
// Test AVL
35+
var startNow1 = new DateTime.now();
36+
var startTime1 = startNow1.millisecondsSinceEpoch;
37+
38+
AVLTree<String, num> avl = AVLTree();
39+
for (String word in words) {
40+
if (avl.contains(word))
41+
avl.set(word, avl.get(word) + 1);
42+
else
43+
avl.add(word, 1);
44+
}
45+
46+
for(String word in words)
47+
avl.contains(word);
48+
var endNow1 = new DateTime.now();
49+
var endTime1 = endNow1.millisecondsSinceEpoch;
50+
51+
time = (endTime1 - startTime1) / 1000.0;
52+
print("AVL: $time s");
53+
54+
55+
}

0 commit comments

Comments
 (0)