Skip to content

Commit dbfe0a0

Browse files
committed
update
1 parent 9625473 commit dbfe0a0

File tree

9 files changed

+106
-85
lines changed

9 files changed

+106
-85
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154

155155
### 博客与网站
156156

157+
* [DataStructure](https://www.growingwiththeweb.com/p/explore.html?t=Data%20structure)
157158
* The-Art-Of-Programming-By-July : [\[GitHub\]](https:/github.com/julycoding/The-Art-Of-Programming-By-July)
158159
* leetcode : [[leetcode]](http:/leetcode.com/)
159160
* 算法和数据结构词典:[[Dictionary of Algorithms and Data Structures]](https:/xlinux.nist.gov/dads/)

src/heap/BinomialHeap.js

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,49 @@
1-
const Comparator = require("../common/Comparator");
2-
3-
/**
4-
* BinomialHeapNode
5-
*/
6-
class BinomialHeapNode {
7-
8-
/**
9-
* BinomialHeapNode
10-
* @param {*} value value of this node
11-
*/
12-
constructor(value) {
13-
this._value = value;
14-
this._degree = 0;
15-
this._parent = null;
16-
this._child = null;
17-
this._sibling = null;
18-
}
1+
// TODO: BinomialHeap
192

20-
/**
21-
* getter of value
22-
*/
23-
get value() {
24-
return this._value;
25-
}
26-
}
3+
const Comparator = require("../common/Comparator");
274

285
/**
296
* BinomialHeap
307
*/
318
class BinomialHeap {
9+
3210
/**
3311
* 构造
3412
* @param {Function} fn comparator function
3513
*/
3614
constructor(fn = null) {
37-
this.comparator = new Comparator(fn);
15+
3816
}
3917

4018
/**
4119
* Clears the heap's data, making it an empty heap.
4220
*/
43-
clear() {}
21+
clear() {
22+
23+
}
4424

4525
/**
46-
* pop and returns the minimum node value from the heap.
47-
* @return {*}} node value of this heap's minimum node or null if the heap is empty.
26+
* Inserts a new key-value pair into the heap.
27+
* @param {*} value The value to insert.
28+
* @return {BinomialTreeNode} node The inserted node.
4829
*/
49-
pop() {}
30+
insert(value) {
31+
32+
}
5033

5134
/**
5235
* Returns the minimum node from the heap.
5336
* @return {*} node value of this heap's minimum node or null if the heap is empty.
5437
*/
55-
peek() {}
38+
peek() {
39+
40+
}
5641

5742
/**
58-
* Inserts a new key-value pair into the heap.
59-
* @param {*} value The value to insert.
60-
* @return {BinomialHeapNode} node The inserted node.
43+
* pop and returns the minimum node value from the heap.
44+
* @return {*} node value of this heap's minimum node or null if the heap is empty.
6145
*/
62-
insert(value) {
46+
pop() {
6347

6448
}
6549

@@ -73,15 +57,16 @@ class BinomialHeap {
7357

7458
/**
7559
* Decreases value of a node.
76-
* @param {BinomialHeapNode} node node to decrease the key of.
60+
* @param {BinomialTreeNode} node node to decrease the key of.
7761
* @param {value} value new value to assign to the node.
7862
*/
79-
decrease(node, value) {}
63+
decrease(node, value) {
8064

65+
}
8166

8267
/**
8368
* Deletes a node.
84-
* @param {BinomialHeapNode} node The node to delete.
69+
* @param {BinomialTreeNode} node The node to delete.
8570
*/
8671
delete(node) {
8772

src/heap/FibonacciHeap.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,6 @@
22

33
const Comparator = require("../common/Comparator");
44

5-
/**
6-
* FibonacciHeapNode
7-
*/
8-
class FibonacciHeapNode {
9-
10-
/**
11-
* FibonacciHeapNode
12-
* @param {*} value value of this node
13-
*/
14-
constructor(value) {
15-
this._value = value;
16-
this._prev = this;
17-
this._next = this;
18-
this._degree = 0;
19-
this._parent = null;
20-
this._child = null;
21-
this._marked = null;
22-
}
23-
24-
/**
25-
* getter of value
26-
*/
27-
get value() {
28-
return this._value;
29-
}
30-
}
315
/**
326
* FibonacciHeap
337
*/

test/index.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
// TREE
2-
// require("./tree/tree.BinarySearchTreeCommon.test")
3-
// require("./tree/tree.BinarySearchTree.test");
4-
// require("./tree/tree.AVLTree.test");
5-
// require("./tree/tree.SplayTree.test");
6-
// require("./tree/tree.RedBlackTree.test");
7-
// require("./tree/tree.Treap.test");
2+
require("./tree/tree.BinarySearchTreeCommon.test")
3+
require("./tree/tree.BinarySearchTree.test");
4+
require("./tree/tree.AVLTree.test");
5+
require("./tree/tree.SplayTree.test");
6+
require("./tree/tree.RedBlackTree.test");
7+
require("./tree/tree.Treap.test");
88

99
// HEAP
10-
// require("./heap/heap.HeapCommon.test");
11-
// require("./heap/heap.MinHeap.test");
12-
// require("./heap/heap.MaxHeap.test");
13-
// require("./heap/heap.LeftistHeap.test");
14-
require("./heap/heap.BinomialHeap.test");
15-
require("./heap/heap.FibonacciHeap.test");
10+
require("./heap/heap.HeapCommon.test");
11+
require("./heap/heap.MinHeap.test");
12+
require("./heap/heap.MaxHeap.test");
13+
require("./heap/heap.LeftistHeap.test");
14+
// require("./heap/heap.BinomialHeap.test");
15+
// require("./heap/heap.FibonacciHeap.test");
1616

1717
// HASH
18-
require("./hash/hash.HashSet.test");
19-
require("./hash/hash.HashTable.test");
18+
// require("./hash/hash.HashSet.test");
19+
// require("./hash/hash.HashTable.test");

树形数据结构/Heap.md

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
1. 每个节点的Key大于(或小于)子节点的Key
2626
2. 对于任意节点的左右两个子节点,右子节点的`npl`不大于左子节点的`npl`.
2727

28-
可以证明 如果一个左倾堆的右侧路径上有r个节点那么该左倾堆将至少有2^r-1个节点,整个左倾堆至少有2^(r+1)-1个节点,因此如果沿着右侧路径合并,复杂度
28+
可以证明 如果一个左倾堆的右侧路径上有r个节点,那么该左倾堆将至少有2^r-1个节点,整个左倾堆至少有2^(r+1)-1个节点,因此如果沿着右侧路径合并,复杂度
2929
为log(n).
3030

3131
左倾堆合并算法:
@@ -54,7 +54,7 @@
5454
* 每个节点只有一个孩子指针,指向第一个孩子
5555
* 每个节点有一个邻居指针,指向下一个邻居,通过孩子指针和孩子指针的邻居指针可以遍历所有的孩子.
5656

57-
![BinomialTree](img/BinomialTree.jpg)
57+
![BinomialTree](img/BinomialTrees.png)
5858

5959
二项堆是指满足以下性质的二项树的集合:
6060

@@ -67,6 +67,32 @@
6767

6868
最基本的为二个度数相同的二项树的合并,由于二项树根结点包含最小的关键字,因此在二颗树合并时,只需比较二个根结点关键字的大小,其中含小关键字的结点成为结果树的根结点,另一棵树则变成结果树的子树
6969

70+
```js
71+
function mergeTree(p, q)
72+
if p.root <= q.root
73+
return p.addSubTree(q)
74+
else
75+
return q.addSubTree(p)
76+
```
77+
78+
![二个度数相同的二项树的合并](./img/Binomial_heap_merge1.png)
79+
80+
两个二项堆的合并则可按如下步骤进行:度数 j从小取到大,在两个二项堆中如果其中只有一棵树的度数为 j,即将此树移动到结果堆,而如果只两棵树的度数都为 j,则根据以上方法合并为一个度数为 j+1 的二项树.此后这个度数为 j+1 的树将可能会和其他度数为 j+1 的二项树进行合并.因此,对于任何度数j,可能最多需要合并3棵二项树.
81+
82+
此操作的时间复杂度为 O(log n).
83+
84+
```js
85+
function merge(p, q)
86+
while not (p.end() and q.end())
87+
tree = mergeTree(p.currentTree(), q.currentTree())
88+
if not heap.currentTree().empty()
89+
tree = mergeTree(tree, heap.currentTree())
90+
heap.addTree(tree)
91+
heap.next(); p.next(); q.next()
92+
```
93+
94+
![二项堆的合并](./img/Binomial_heap_merge2.png)
95+
7096
### 插入
7197

7298
创建一个只包含要插入元素的二项堆,再将此堆与原先的二项堆进行合并,即可得到插入后的堆.由于需要合并,插入操作需要O(logn)的时间.平摊分析的时间复杂度为O(1)
@@ -79,6 +105,17 @@
79105

80106
先找到最小关键字所在结点,然后将它从其所在的二项树中删除,并获得其子树,将这些子树看作一个独立的二项堆,再将此堆合并到原先的堆中即可
81107

108+
```js
109+
function deleteMin(heap)
110+
min = heap.trees().first()
111+
for each current in heap.trees()
112+
if current.root < min then min = current
113+
for each tree in min.subTrees()
114+
tmp.addTree(tree)
115+
heap.removeTree(min)
116+
merge(heap, tmp)
117+
```
118+
82119
### 减小特定结点(关键字)的值
83120

84121
在减小特定结点(关键字)的值后,可能会不满足最小堆积性质.此时,将其所在结点与父结点交换,如还不满足最小堆性质则再与祖父结点交换……直到最小堆性质得到满足.
@@ -87,16 +124,42 @@
87124

88125
将需要删除的结点的关键字的值减小到负无穷大(比二项堆中的其他所有关键字的值都小即可),执行“减小关键字的值”算法,使其调整到当前二项树的根节点位置,再删除最小关键字的根结点即可
89126

127+
以下对于二项堆操作的运行时间都为 O(logn):
128+
129+
* 在二项堆中插入新结点
130+
* 合并两个二项堆
131+
* 查找最小关键字所在结点(可以通过维护最小关键字指针达到 O(1))
132+
* 删除最小关键字所在结点
133+
* 减小给定结点关键字的值
134+
* 删除给定结点
135+
90136
## 斐波那契堆(Fibonacci Heap)
91137

92-
斐波那契堆是一系列无序树的集合,每棵树是一个最小堆,满足最小堆的性质.堆保存了堆中所有节点的数目,保存了最小关键字的节点.
138+
斐波那契堆是由一组最小堆有序树构成的集合,每个最小堆有序树的度数为其子节点的数目,树的度数为其根节点的度数.
93139

94140
斐波那契堆中所有树的根节点也用一个双向循环链表链接起来
95141

96142
使用一个指针指向斐波那契堆中最小元素
97143

144+
斐波那契堆 比二项堆有更好的平摊分析复杂度
145+
98146
![FibonacciHeap](img/FibonacciHeap.jpg)
99147

148+
斐波那契堆的主要操作有:
149+
150+
* 合并两个斐波那契堆(O(1)): 简单合并两个斐波纳契堆的根表.即把两个斐波纳契堆的所有树的根首尾衔接并置
151+
* 在斐波那契堆中插入新结点(O(1)): 创建一个仅包含一个节点的新的斐波纳契堆,然后执行堆合并.
152+
* 查找最小关键字所在结点(O(1)): 由于用一个指针指向了具有最小值的根节点,因此查找最小的节点是简单的操作.
153+
* 删除最小关键字所在结点(平摊分析 O(log(n))): 查找最小的根节点并删除它,其所有的子节点都加入堆的根表,然后维护根表(维护根表: 然后对根表中当前包含的树的度数从低到高,迭代执行具有相同度数的树的合并并实现最小树化调整,使得堆包含的树具有不同的度数)
154+
* 减小给定结点关键字的值(平摊分析 O(1)): 对一个节点的键值降低后,自键值降低的节点开始自下而上的迭代执行下述操作,直至到根节点或一个未被标记(marked)节点为止
155+
如果当前节点键值小于其父节点的键值,则把该节点及其子树摘下来作为堆的新树的根节点;其原父节点如果是被标记(marked)节点,则也被摘下来作为堆的新树的根节点;如果其原父节点不是被标记(marked)节点且不是根节点,则其原父节点被加标记.
156+
* 删除给定结点(平摊分析 O(log(n))): 把被删除节点的键值调整为负无穷小,然后减小给定结点关键字的值,然后再删除最小关键字所在结点
157+
100158
## 优先队列(Priority Queue)
101159

102-
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有最高级先出(**first in, largest out**)的行为特征.通常采用堆数据结构来实现.
160+
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有最高级先出(**first in, largest out**)的行为特征.通常采用堆(例如二项堆,斐波那契堆等)数据结构来实现.
161+
162+
## Reference
163+
164+
[binomial-heap/overview](https://www.growingwiththeweb.com/data-structures/binomial-heap/overview/)
165+
[fibonacci-heap/overview](https://www.growingwiththeweb.com/data-structures/fibonacci-heap/overview/)

树形数据结构/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@
4242
## [](./Heap.md)
4343

4444
* [二叉堆(大根堆 小根堆)](./Heap.md#二叉堆)
45-
* [二项树](./Heap.md#二项树)
46-
* [二项堆](./Heap.md#二项堆)
4745
* [左倾堆](./Heap.md#左倾堆)
46+
* [二项堆](./Heap.md#二项堆)
4847
* [斐波那契堆(Fibonacci Heap)](./Heap.md#斐波那契堆)
49-
* [优先队列(Priority Queue)](./Heap.md#优先队列)
5048

5149
## 其他树/树形结构
5250

11.7 KB
Loading
19.3 KB
Loading
21.2 KB
Loading

0 commit comments

Comments
 (0)