Skip to content

Commit 058401a

Browse files
author
tianqing.liang
committed
哈希表
1 parent 274945e commit 058401a

File tree

11 files changed

+30706
-0
lines changed

11 files changed

+30706
-0
lines changed

21-Hash-Table/AVLTree.dart

Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
import 'dart:math';
2+
import 'FileOperator.dart';
3+
4+
/**
5+
* AVL树
6+
* 第一个自平衡的树
7+
*
8+
* 添加,删除
9+
* LL,RR,RL,LR
10+
*
11+
* 平衡二叉树
12+
* 每个节点的左右子树高度相差1
13+
*/
14+
class AVLTree<K extends Comparable<K>, V> {
15+
_Node? root;
16+
17+
int? size;
18+
19+
AVLTree() {
20+
root = null;
21+
size = 0;
22+
}
23+
24+
@override
25+
add(key, value) {
26+
root = _addNode(root, key, value);
27+
}
28+
29+
_Node? _addNode(_Node? node, K key, V value) {
30+
if (node == null) {
31+
size = size! + 1;
32+
return new _Node(key, value);
33+
}
34+
35+
if (key.compareTo(node._key) < 0) {
36+
node.left = _addNode(node.left, key, value);
37+
} else if (key.compareTo(node._key) > 0) {
38+
node.right = _addNode(node.right, key, value);
39+
} else {
40+
// key.compareTo(node.key) == 0
41+
node._value = value;
42+
}
43+
//更新height
44+
node.height =
45+
1 + [_getHeight(node.left), _getHeight(node.right)].reduce(max);
46+
// 计算平衡因子
47+
int balanceFactor = getBalanceFactor(node);
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);
64+
}
65+
return node;
66+
}
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+
114+
// 判断该二叉树是否是一棵平衡二叉树
115+
bool isBalanced() {
116+
return _isBalancedDetail(root);
117+
}
118+
119+
// 判断以Node为根的二叉树是否是一棵平衡二叉树,递归算法
120+
bool _isBalancedDetail(_Node? node) {
121+
if (node == null) return true;
122+
123+
int balanceFactor = getBalanceFactor(node);
124+
if (balanceFactor.abs() > 1) return false;
125+
return _isBalancedDetail(node.left) && _isBalancedDetail(node.right);
126+
}
127+
128+
//获得节点node的平衡因子
129+
int getBalanceFactor(_Node? node) {
130+
if (node == null) {
131+
return 0;
132+
}
133+
return _getHeight(node.left) - _getHeight(node.right);
134+
}
135+
136+
// 判断该二叉树是否是一棵二分搜索树
137+
bool isBST() {
138+
List keys = List.empty(growable: true);
139+
_inOrder(root, keys);
140+
for (int i = 1; i < keys.length; i++) {
141+
if (keys[i - 1].compareTo(keys[i]) > 0) {
142+
return false;
143+
}
144+
}
145+
return true;
146+
}
147+
148+
_inOrder(_Node? node, List? keys) {
149+
if (node == null) return;
150+
151+
_inOrder(node.left, keys);
152+
keys!.add(node._key);
153+
_inOrder(node.right, keys);
154+
}
155+
156+
_Node? _getNode(_Node? node, K key) {
157+
if (node == null) {
158+
return null;
159+
}
160+
161+
if (key.compareTo(node._key) == 0) {
162+
return node;
163+
} else if (key.compareTo(node._key) < 0) {
164+
return _getNode(node.left, key);
165+
} else {
166+
// if(key.compareTo(node.key) > 0)
167+
return _getNode(node.right, key);
168+
}
169+
}
170+
171+
@override
172+
bool contains(key) {
173+
return _getNode(root, key) != null;
174+
}
175+
176+
@override
177+
get(key) {
178+
_Node? node = _getNode(root, key);
179+
return node == null ? null : node._value;
180+
}
181+
182+
@override
183+
int? getSize() {
184+
return size;
185+
}
186+
187+
@override
188+
bool isEmpty() {
189+
return size == 0;
190+
}
191+
192+
// 获得节点node的高度
193+
int _getHeight(_Node? node) {
194+
if (node == null) return 0;
195+
return node.height;
196+
}
197+
198+
@override
199+
remove(key) {
200+
_Node? node = _getNode(root, key);
201+
if (node != null) {
202+
root = _removeNode(root!, key);
203+
return node._value;
204+
}
205+
return null;
206+
}
207+
208+
_Node? _removeNode(_Node node, K key) {
209+
if (node == null) {
210+
return null;
211+
}
212+
_Node? retNode;
213+
if (key.compareTo(node._key) < 0) {
214+
node.left = _removeNode(node.left!, key);
215+
// return node;
216+
retNode = node;
217+
} else if (key.compareTo(node._key) > 0) {
218+
node.right = _removeNode(node.right!, key);
219+
// return node;
220+
retNode = node;
221+
} else {
222+
// 待删除节点左子树为空的情况
223+
if (node.left == null) {
224+
_Node? rightNode = node.right;
225+
node.right = null;
226+
size = size! - 1;
227+
// return rightNode;
228+
retNode = rightNode;
229+
}
230+
// 待删除节点右子树为空的情况
231+
if (node.right == null) {
232+
_Node? leftNode = node.left;
233+
node.left = null;
234+
size = size! - 1;
235+
// return leftNode;
236+
retNode = leftNode;
237+
}
238+
// 待删除节点左右子树均不为空的情况
239+
// 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
240+
// 用这个节点顶替待删除节点的位置
241+
_Node successor = _minimum(node.right!);
242+
//w维持平衡性操作,不再执行removemin
243+
successor.right = _removeNode(node.right!, successor._key);
244+
successor.left = node.left;
245+
node.left = node.right = null;
246+
// return successor;
247+
retNode = successor;
248+
}
249+
if (retNode == null) {
250+
return null;
251+
}
252+
253+
// 更新height
254+
retNode.height =
255+
1 + [_getHeight(retNode.left), _getHeight(retNode.right)].reduce(max);
256+
257+
// 计算平衡因子
258+
int balanceFactor = getBalanceFactor(retNode);
259+
260+
// 平衡维护
261+
// LL
262+
if (balanceFactor > 1 && getBalanceFactor(retNode.left) >= 0)
263+
return _rightRotate(retNode);
264+
265+
// RR
266+
if (balanceFactor < -1 && getBalanceFactor(retNode.right) <= 0)
267+
return _leftRotate(retNode);
268+
269+
// LR
270+
if (balanceFactor > 1 && getBalanceFactor(retNode.left) < 0) {
271+
retNode.left = _leftRotate(retNode.left!);
272+
return _rightRotate(retNode);
273+
}
274+
275+
// RL
276+
if (balanceFactor < -1 && getBalanceFactor(retNode.right) > 0) {
277+
retNode.right = _rightRotate(retNode.right!);
278+
return _leftRotate(retNode);
279+
}
280+
281+
return retNode;
282+
}
283+
284+
// 删除掉以node为根的二分搜索树中的最小节点
285+
// 返回删除节点后新的二分搜索树的根
286+
_Node _removeMin(_Node node) {
287+
if (node.left == null) {
288+
_Node? rightNode = node.right;
289+
node.right = null;
290+
size = size! - 1;
291+
return rightNode!;
292+
}
293+
node.left = _removeMin(node.left!);
294+
return node;
295+
}
296+
297+
// 返回以node为根的二分搜索树的最小值所在的节点
298+
_Node _minimum(_Node node) {
299+
if (node.left == null) {
300+
return node;
301+
}
302+
return _minimum(node.left!);
303+
}
304+
305+
@override
306+
set(key, newValue) {
307+
_Node? node = _getNode(root, key);
308+
if (node == null) {
309+
throw new Exception(" $key + doesn't exist!");
310+
}
311+
node._value = newValue;
312+
}
313+
}
314+
315+
class _Node<K, V> {
316+
K? _key;
317+
318+
V? _value;
319+
320+
_Node? left, right;
321+
322+
int height = 1;
323+
324+
_Node(K key, V value) {
325+
this._key = key;
326+
this._value = value;
327+
left = null;
328+
right = null;
329+
}
330+
}
331+
332+
void main() async {
333+
List result = await FileOperator.getFileString('text2.txt');
334+
AVLTree<String, int> map = AVLTree();
335+
for (String word in result) {
336+
if (map.contains(word))
337+
map.set(word, map.get(word) + 1);
338+
else
339+
map.add(word, 1);
340+
}
341+
print("Total different words: ${map.getSize()}");
342+
print("Frequency of PRIDE: ${map.get("pride")}");
343+
print("Frequency of PREJUDICE: ${map.get("prejudice")}");
344+
345+
print("is BST : ${map.isBST()}");
346+
print("is Balanced : ${map.isBalanced()}");
347+
}

0 commit comments

Comments
 (0)