Skip to content

Commit 1c161a7

Browse files
committed
tree例子
1 parent e761506 commit 1c161a7

File tree

8 files changed

+679
-92
lines changed

8 files changed

+679
-92
lines changed

examples/chapter10/inorder.js

-17
This file was deleted.

examples/chapter10/postorder.html

-10
This file was deleted.

examples/chapter10/postorder.js

-11
This file was deleted.

examples/chapter10/preorder.html

-10
This file was deleted.

examples/chapter10/preorder.js

-43
This file was deleted.

examples/chapter10/inorder.html examples/chapter10/tree.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<title></title>
66
</head>
77
<body>
8-
<script src="inorder.js"></script>
8+
<img src="./tree.svg" alt="">
9+
<script src="tree.js"></script>
910
</body>
1011
</html>

examples/chapter10/tree.js

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
2+
const Compare = {
3+
LESS_THAN: -1,
4+
BIGGER_THAN: 1,
5+
EQUALS: 0
6+
};
7+
8+
function defaultCompare(a, b) {
9+
if (a === b) {
10+
return Compare.EQUALS;
11+
}
12+
return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN;
13+
}
14+
class Node {
15+
constructor(key) {
16+
this.key = key;
17+
this.left = undefined;
18+
this.right = undefined;
19+
}
20+
21+
toString() {
22+
return `${this.key}`;
23+
}
24+
}
25+
class BinarySearchTree {
26+
constructor(compareFn = defaultCompare) {
27+
this.compareFn = compareFn;
28+
this.root = undefined;
29+
}
30+
31+
insert(key) {
32+
// special case: first key
33+
if (this.root == null) {
34+
this.root = new Node(key);
35+
} else {
36+
this.insertNode(this.root, key);
37+
}
38+
}
39+
40+
insertNode(node, key) {
41+
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
42+
if (node.left == null) {
43+
node.left = new Node(key);
44+
} else {
45+
this.insertNode(node.left, key);
46+
}
47+
} else if (node.right == null) {
48+
node.right = new Node(key);
49+
} else {
50+
this.insertNode(node.right, key);
51+
}
52+
}
53+
54+
getRoot() {
55+
return this.root;
56+
}
57+
58+
search(key) {
59+
return this.searchNode(this.root, key);
60+
}
61+
62+
searchNode(node, key) {
63+
if (node == null) {
64+
return false;
65+
}
66+
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
67+
return this.searchNode(node.left, key);
68+
} if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
69+
return this.searchNode(node.right, key);
70+
}
71+
return true;
72+
}
73+
74+
inOrderTraverse(callback) {
75+
this.inOrderTraverseNode(this.root, callback);
76+
}
77+
78+
inOrderTraverseNode(node, callback) {
79+
if (node != null) {
80+
this.inOrderTraverseNode(node.left, callback);
81+
callback(node.key);
82+
this.inOrderTraverseNode(node.right, callback);
83+
}
84+
}
85+
86+
preOrderTraverse(callback) {
87+
this.preOrderTraverseNode(this.root, callback);
88+
}
89+
90+
preOrderTraverseNode(node, callback) {
91+
if (node != null) {
92+
callback(node.key);
93+
this.preOrderTraverseNode(node.left, callback);
94+
this.preOrderTraverseNode(node.right, callback);
95+
}
96+
}
97+
98+
postOrderTraverse(callback) {
99+
this.postOrderTraverseNode(this.root, callback);
100+
}
101+
102+
postOrderTraverseNode(node, callback) {
103+
if (node != null) {
104+
this.postOrderTraverseNode(node.left, callback);
105+
this.postOrderTraverseNode(node.right, callback);
106+
callback(node.key);
107+
}
108+
}
109+
110+
min() {
111+
return this.minNode(this.root);
112+
}
113+
114+
minNode(node) {
115+
let current = node;
116+
while (current != null && current.left != null) {
117+
current = current.left;
118+
}
119+
return current;
120+
}
121+
122+
max() {
123+
return this.maxNode(this.root);
124+
}
125+
126+
maxNode(node) {
127+
let current = node;
128+
while (current != null && current.right != null) {
129+
current = current.right;
130+
}
131+
return current;
132+
}
133+
134+
remove(key) {
135+
this.root = this.removeNode(this.root, key);
136+
}
137+
138+
removeNode(node, key) {
139+
if (node == null) {
140+
return undefined;
141+
}
142+
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
143+
node.left = this.removeNode(node.left, key);
144+
return node;
145+
} if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
146+
node.right = this.removeNode(node.right, key);
147+
return node;
148+
}
149+
// key is equal to node.item
150+
// handle 3 special conditions
151+
// 1 - a leaf node
152+
// 2 - a node with only 1 child
153+
// 3 - a node with 2 children
154+
// case 1
155+
if (node.left == null && node.right == null) {
156+
node = undefined;
157+
return node;
158+
}
159+
// case 2
160+
if (node.left == null) {
161+
node = node.right;
162+
return node;
163+
} if (node.right == null) {
164+
node = node.left;
165+
return node;
166+
}
167+
// case 3
168+
const aux = this.minNode(node.right);
169+
node.key = aux.key;
170+
node.right = this.removeNode(node.right, aux.key);
171+
return node;
172+
}
173+
}
174+
175+
const tree = new BinarySearchTree();
176+
tree.insert(1);
177+
tree.insert(3);
178+
tree.insert(8);
179+
tree.insert(10);
180+
tree.insert(14);
181+
tree.insert(13);
182+
tree.insert(4);
183+
tree.insert(6);
184+
tree.insert(7);
185+
console.log(tree);
186+
tree.inOrderTraverse((v) => document.write(`${v}\n`));

0 commit comments

Comments
 (0)