Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 70356b0

Browse files
committed
学习 堆和优先队列
1 parent fe17b57 commit 70356b0

File tree

9 files changed

+134
-16
lines changed

9 files changed

+134
-16
lines changed

‎src/data-structures/doubly-linked-list/README.zh-CN.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
在双向链表中进行添加或者删除节点时,需做的链接更改要比单向链表复杂得多。这种操作在单向链表中更简单高效,因为不需要关注一个节点(除第一个和最后一个节点以外的节点)的两个链接,而只需要关注一个链接即可。
1212

13+
## 基本操作
14+
15+
同链表
16+
1317
## 基础操作的伪代码
1418

1519
### 插入

‎src/data-structures/hash-table/HashTable.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export default class HashTable {
3535
//
3636
// where charCodeAt(i) is the i-th character code of the key, n is the length of the key and
3737
// PRIME is just any prime number like 31.
38+
// 求和取余
3839
const hash = Array.from(key).reduce(
3940
(hashAccumulator, keySymbol) => (hashAccumulator + keySymbol.charCodeAt(0)),
4041
0,

‎src/data-structures/hash-table/README.zh-CN.md‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,20 @@
55

66
哈希表使用 *哈希函数/散列函数* 来计算一个值在数组或桶(buckets)中或槽(slots)中对应的索引,可使用该索引找到所需的值。
77

8+
## 基本操作
9+
10+
- hash 计算 hash 值
11+
- set
12+
- get
13+
- delete
14+
- has
15+
- getKeys
16+
817
## 伪代码
918

1019
### 计算 hash
1120

12-
为简单起见,我们将只使用密钥中所有字符的字符代码和计算散列值。但也可以使用更复杂的方法,如多项式字符串哈希来减少碰撞次数:
21+
为简单起见,我们将只使用密钥中所有字符的字符代码**求和取余**计算散列值。但也可以使用更复杂的方法,如多项式字符串哈希来减少碰撞次数:
1322

1423
```text
1524
hash = charCodeAt(0) * PRIME^(n-1) + charCodeAt(1) * PRIME^(n-2) + ... + charCodeAt(n-1)
@@ -31,6 +40,8 @@ end Hash
3140

3241
理想情况下,散列函数将为每个键分配给一个唯一的桶(bucket),但是大多数哈希表设计采用不完美的散列函数,这可能会导致"哈希冲突(hash collisions)",也就是散列函数为多个键(key)生成了相同的索引,这种碰撞必须以某种方式进行处理。
3342

43+
如果存在冲突则 `append` 处理,否则直接赋值
44+
3445
![Hash Table](./images/hash-table.jpeg)
3546

3647
*Made with [okso.app](https://okso.app)*

‎src/data-structures/heap/Heap.js‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Comparator from '../../utils/comparator/Comparator';
22

33
/**
44
* Parent class for Min and Max Heaps.
5+
* 这里的堆实际上是二叉堆(Binary Heap),其实也可定义k叉堆。
56
*/
67
export default class Heap {
78
/**
@@ -36,7 +37,7 @@ export default class Heap {
3637

3738
/**
3839
* @param {number} childIndex
39-
* @return {number}
40+
* @return {number} 向下取整
4041
*/
4142
getParentIndex(childIndex) {
4243
return Math.floor((childIndex - 1) / 2);
@@ -67,27 +68,27 @@ export default class Heap {
6768
}
6869

6970
/**
70-
* @param {number} parentIndex
71+
* @param {number} childIndex
7172
* @return {*}
7273
*/
73-
leftChild(parentIndex) {
74-
return this.heapContainer[this.getLeftChildIndex(parentIndex)];
74+
parent(childIndex) {
75+
return this.heapContainer[this.getParentIndex(childIndex)];
7576
}
7677

7778
/**
7879
* @param {number} parentIndex
7980
* @return {*}
8081
*/
81-
rightChild(parentIndex) {
82-
return this.heapContainer[this.getRightChildIndex(parentIndex)];
82+
leftChild(parentIndex) {
83+
return this.heapContainer[this.getLeftChildIndex(parentIndex)];
8384
}
8485

8586
/**
86-
* @param {number} childIndex
87+
* @param {number} parentIndex
8788
* @return {*}
8889
*/
89-
parent(childIndex) {
90-
return this.heapContainer[this.getParentIndex(childIndex)];
90+
rightChild(parentIndex) {
91+
return this.heapContainer[this.getRightChildIndex(parentIndex)];
9192
}
9293

9394
/**

‎src/data-structures/heap/README.zh-CN.md‎

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,54 @@
1414

1515
![Array Representation](./images/array-representation.jpeg)
1616

17+
在堆"顶部"的没有父级节点的节点, 被称之为根节点。
1718

18-
在堆"顶部"的没有父级节点的节点,被称之为根节点。
19+
## 基本操作
20+
21+
堆就是用数组实现的一棵完全二叉树(在时间和空间上很高效),堆是完全二叉树,索引值具有以下关系
22+
23+
```text
24+
parent(index)
25+
/ \
26+
left(2*index+1) right(2*index+2)
27+
28+
- 第 h 层第 n 个元素是 `2 ^ h + n`
29+
- 索引:父计算子
30+
leftChildIndex 为 `parentIndex * 2 + 1`
31+
rightChildIndex 为 `parentIndex * 2 + 2`
32+
- 索引:子计算父
33+
parentIndex 为 `(childIndex - 1) / 2` 后向下取整
34+
35+
因为上面索引值的关系,这也就是为什么可以直接用数组来存储堆的原因。
36+
```
37+
38+
- 索引、父子元素等操作
39+
- getLeftChildIndex
40+
- getRightChildIndex
41+
- getParentIndex
42+
- hasParent 通过索引值有效性来判断
43+
- hasLeftChild
44+
- hasRightChild
45+
- parent 通过索引值获取
46+
- leftChild
47+
- rightChild
48+
- swap 两个值交换位置
49+
- peek 仅仅读取最小值或最大值
50+
- poll 从堆中提取最小值或最大值 `O(1)`
51+
- add 向堆中插入一个新元素 insert(value)
52+
- buildHeap(array) 通过反复调用 `insert()` 方法将一个(无序)数组转换成一个堆。如果你足够聪明,你可以在 `O(n)` 时间内完成。
53+
- remove 删除堆元素 delete removeAtIndex(index)
54+
- find search(value)
55+
- isEmpty
56+
- toString
57+
- 原始操作,用于保证插入或删除节点以后使其符合堆的性质
58+
- heapifyUp 将新元素提升使其符合堆的性质
59+
- heapifyDown 使删除堆顶元素的堆再次成为堆
60+
- pairIsInCorrectOrder 检查堆元素的顺序是否正确
1961

2062
## 参考
2163

2264
- [Wikipedia](https://en.wikipedia.org/wiki/Heap_(data_structure))
2365
- [YouTube](https://www.youtube.com/watch?v=t0Cq6tVNRBA&index=5&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
66+
- [数据结构之"堆"](http://www.cnblogs.com/Jason-Damon/archive/2012/04/18/2454649.html)
67+
- [数据结构:堆(Heap)](https://www.jianshu.com/p/6b526aa481b1)

‎src/data-structures/linked-list/README.zh-CN.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@
1212

1313
*Made with [okso.app](https://okso.app)*
1414

15+
## 基本操作
16+
17+
- 插入
18+
- prepend
19+
- append
20+
- 搜索
21+
- find
22+
- 删除
23+
- delete
24+
- deleteHead
25+
- deleteTail
26+
- 辅助
27+
- toArray
28+
- fromArray
29+
- toString
30+
- reverse
31+
- 其他
32+
- 遍历
33+
- 反向遍历
34+
1535
## 基本操作的伪代码
1636

1737
[伪代码格式](https://blog.csdn.net/ssisse/article/details/51501797)

‎src/data-structures/priority-queue/README.zh-CN.md‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,32 @@
44

55
在优先队列中, 低优先级的元素之前前面应该是高优先级的元素。 如果两个元素具有相同的优先级, 则根据它们在队列中的顺序是它们的出现顺序即可。
66

7-
优先队列虽通常用堆来实现,但它在概念上与堆不同。优先队列是一个抽象概念,就像"列表"或"图"这样的抽象概念一样;
7+
优先队列虽通常用堆来实现,但它在概念上与堆不同。优先队列是一个抽象概念, 就像"列表"或"图"这样的抽象概念一样;
88

9-
正如列表可以用链表或数组实现一样,优先队列可以用堆或各种其他方法实现,例如无序数组。
9+
正如列表可以用链表或数组实现一样, 优先队列可以用堆或各种其他方法实现,例如无序数组。
1010

11+
## 基本操作
12+
13+
此处实现 inherit MinHeap,按优先级排序存储数据
14+
15+
- add
16+
- remove
17+
- changePriority
18+
- findByValue
19+
- hasValue
20+
- comparePriority
21+
- compareValue
22+
23+
优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素,C++的优先队列每次取最大元素)。这里牵涉到了大小关系,元素大小的评判可以通过元素本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator,类似于C++的仿函数)。
24+
25+
优先队列的应用比较广泛,比如作业系统中的调度程序,当一个作业完成后,需要在所有等待调度的作业中选择一个优先级最高的作业来执行,并且也可以添加一个新的作业到作业的优先队列中。
26+
27+
问题:
28+
29+
这里执行 poll 时,优先队列里存储的优先级并未删除,可以覆写处理
1130

1231
## 参考
1332

1433
- [Wikipedia](https://en.wikipedia.org/wiki/Priority_queue)
1534
- [YouTube](https://www.youtube.com/watch?v=wptevk0bshY&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=6)
35+
- [深入理解Java PriorityQueue](http://www.cnblogs.com/CarpenterLee/p/5488070.html)

‎src/data-structures/queue/README.zh-CN.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44

55
队列基本操作有两种:入队和出队。从队列的后端位置添加实体,称为入队;从队列的前端位置移除实体,称为出队。
66

7-
87
队列中元素先进先出 FIFO (first in, first out)的示意
98

109
![Queue](./images/queue.jpeg)
1110

1211
*Made with [okso.app](https://okso.app)*
1312

13+
## 基本操作
14+
15+
- peek 读取队首 value
16+
- enqueue 队尾入队
17+
- dequeue 队首出队
18+
- toString
19+
- isEmpty
20+
1421
## 参考
1522

1623
- [Wikipedia](https://en.wikipedia.org/wiki/Queue_(abstract_data_type))

‎src/data-structures/stack/README.zh-CN.md‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
在计算机科学中, 一个 **栈(stack)** 是一种抽象数据类型,用作表示元素的集合,具有两种主要操作:
44

5-
* **push**, 添加元素到栈的顶端(末尾);
6-
* **pop**, 移除栈最顶端(末尾)的元素.
5+
- **push**, 添加元素到栈的顶端(末尾);
6+
- **pop**, 移除栈最顶端(末尾)的元素.
77

88
以上两种操作可以简单概括为"后进先出(LIFO = last in, first out)"。
99

@@ -17,6 +17,16 @@
1717

1818
*Made with [okso.app](https://okso.app)*
1919

20+
## 基本操作
21+
22+
- push
23+
- pop
24+
- peek
25+
- 辅助
26+
- isEmpty
27+
- toArray
28+
- toString
29+
2030
## 参考
2131

2232
- [Wikipedia](https://en.wikipedia.org/wiki/Stack_(abstract_data_type))

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /