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 3730796

Browse files
committed
增加队列和优先队列的封装及代码测试
1 parent 673eec9 commit 3730796

File tree

8 files changed

+444
-13
lines changed

8 files changed

+444
-13
lines changed

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [JavaScript 数据结构与算法(一)前言](./assets/doc/JavaScript数据结构与算法(一)前言.md)
66
- [JavaScript 数据结构与算法(二)数组结构](./assets/doc/JavaScript数据结构与算法(二)数组结构.md)
77
- [JavaScript 数据结构与算法(三)栈结构](./assets/doc/JavaScript数据结构与算法(三)栈结构.md)
8+
- [JavaScript 数据结构与算法(四)队列结构](./assets/doc/JavaScript数据结构与算法(四)队列结构.md)
89

910
## 代码测试环境
1011

‎assets/doc/JavaScript数据结构与算法(一)前言.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
### 常见的数据结构
5757

5858
- 数组(Aarray)
59-
- 栈(Stack)
59+
- 栈(Queue)
6060
- 链表(Linked List)
6161
- 图(Graph)
6262
- 散列表(Hash)

‎assets/doc/JavaScript数据结构与算法(三)栈结构.md‎

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
---
2-
title: JavaScript 数据结构与算法(三)栈结构
3-
date: 2020年07月21日 11:49:12
4-
tags: [JavaScript, 数据结构, 算法, 栈]
5-
categories: [算法专辑]
6-
---
1+
## JavaScript 数据结构与算法(三)栈结构
72

83
数组是一个线性结构,并且可以在数组的任意位置插入和删除元素。
94
但是有时候,我们为了实现某些功能,必须对这种任意性加以限制。
@@ -27,7 +22,7 @@ categories: [算法专辑]
2722
即 A 函数中调用 B,B 调用 C,C 调用 D;在 A 执行的过程中会将 A 压入栈,随后 B 执行时 B 也被压入栈,函数 C 和 D 执行时也会被压入栈。所以当前栈的顺序为:A->B->C->D(栈顶);函数 D 执行完之后,会弹出栈被释放,弹出栈的顺序为 D->C->B->A;
2823

2924
- 递归:
30-
为什么没有停止条件的递归会造成栈溢出?比如函数 A 为递归函数,不断地调用自己(因为函数还没有执行完,不会把函数弹出栈),不停地把相同的函数 A 压入栈,最后造成栈溢出(Stack Overfloat)。
25+
为什么没有停止条件的递归会造成栈溢出?比如函数 A 为递归函数,不断地调用自己(因为函数还没有执行完,不会把函数弹出栈),不停地把相同的函数 A 压入栈,最后造成栈溢出(Queue Overfloat)。
3126

3227
### 练习
3328

@@ -62,7 +57,7 @@ categories: [算法专辑]
6257

6358
```js
6459
// 使用 ES6 实现
65-
class Stack {
60+
class Queue {
6661
items = [];
6762

6863
// push() 压栈操作,给栈中添加元素
@@ -104,7 +99,7 @@ class Stack {
10499
#### 测试栈结构
105100

106101
```js
107-
const stack = new Stack();
102+
const stack = new Queue();
108103
stack.push(1);
109104
stack.push(22);
110105
stack.push(333);
@@ -128,8 +123,8 @@ console.log(stack.toString()); //--> 1 22
128123
```js
129124
// 十进制转换成二进制
130125
function dec2bin(dec) {
131-
// new 一个 Stack,保存余数
132-
const stack = new Stack();
126+
// new 一个 Queue,保存余数
127+
const stack = new Queue();
133128

134129
// 当不确定循环次数时,使用 while 循环
135130
while (dec > 0) {
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
## JavaScript 数据结构与算法(四)队列结构
2+
3+
### 认识队列
4+
5+
队列(Queue)是一种运算受限的线性表,特点:先进先出。(FIFO:First In First Out)
6+
7+
**受限之处:**
8+
9+
- 只允许在表的前端(front)进行删除操作。
10+
- 在表的后端(rear)进行插入操作。
11+
12+
生活中类似队列结构的场景:
13+
14+
- 排队,,比如在电影院,商场,甚至是厕所排队。
15+
- 优先排队的人,优先处理。 (买票、结账、WC)。
16+
17+
![queue](https://user-images.githubusercontent.com/24516169/88038526-e9f6c880-cb78-11ea-859d-1faaaebed3bf.png)
18+
19+
#### 队列图解
20+
21+
![queue](https://user-images.githubusercontent.com/24516169/88038782-45c15180-cb79-11ea-8439-bdc7e240d10d.png)
22+
23+
#### 队列在程序中的应用
24+
25+
- 打印队列:计算机打印多个文件的时候,需要排队打印。
26+
- 线程队列:当开启多线程时,当新开启的线程所需的资源不足时就先放入线程队列,等待 CPU 处理。
27+
28+
### 队列的实现
29+
30+
队列的实现和栈一样,有两种方案:
31+
32+
- 基于数组实现。
33+
- 基于链表实现。
34+
35+
#### 队列常见的操作
36+
37+
- `enqueue(element)`:向队列尾部添加一个(或多个)新的项。
38+
- `dequeue()`:移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。
39+
- `front()`:返回队列中的第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息与 Stack 类的 peek 方法非常类似)。
40+
- `isEmpty()`:如果队列中不包含任何元素,返回 true,否则返回 false。
41+
- `size()`:返回队列包含的元素个数,与数组的 length 属性类似。
42+
- `toString()`:将队列中的内容,转成字符串形式。
43+
44+
#### 代码实现
45+
46+
```js
47+
// 使用 ES6 实现
48+
class Queue {
49+
items = [];
50+
51+
// enqueue() 入队,将元素加入到队列中
52+
enqueue(item) {
53+
this.items.push(item);
54+
}
55+
56+
// dequeue() 出队,从队列中删除前端元素,返回删除的元素
57+
dequeue() {
58+
return this.items.shift();
59+
}
60+
61+
// front() 查看队列的前端元素
62+
front() {
63+
return this.items[0];
64+
}
65+
66+
// isEmpty() 查看队列是否为空
67+
isEmpty() {
68+
return this.items.length === 0;
69+
}
70+
71+
// size() 查看队列中元素的个数
72+
size() {
73+
return this.items.length;
74+
}
75+
76+
toString() {
77+
let result = "";
78+
for (let item of this.items) {
79+
result += item + " ";
80+
}
81+
return result;
82+
}
83+
}
84+
```
85+
86+
#### 测试代码
87+
88+
```js
89+
const queue = new Queue();
90+
91+
// 入队操作
92+
queue.enqueue("a");
93+
queue.enqueue("b");
94+
queue.enqueue("c");
95+
queue.enqueue("d");
96+
console.log(queue.items); //--> ["a", "b", "c", "d"]
97+
98+
// 出队操作(先进先出)
99+
queue.dequeue();
100+
queue.dequeue();
101+
console.log(queue.items); //--> ["c", "d"]
102+
103+
// 查看队头的元素
104+
console.log(queue.front()); //--> c
105+
106+
console.log(queue.isEmpty()); //--> false
107+
console.log(queue.size()); //--> 2
108+
console.log(queue.toString()); //--> c d
109+
```
110+
111+
### 队列的应用
112+
113+
使用队列实现小游戏:**击鼓传花**
114+
115+
分析:传入一组数据集合和设定的数字 number,循环遍历数组内元素,遍历到的元素为指定数字 number 时将该元素删除,直至数组剩下一个元素。
116+
117+
#### 代码实现
118+
119+
```js
120+
function passGame(nameList, number) {
121+
// 1、new 一个 Queue 对象
122+
const queue = new Queue();
123+
124+
// 2、将 nameList 里面的每一个元素入队
125+
for (const name of nameList) {
126+
queue.enqueue(name);
127+
}
128+
129+
// 3、开始数数
130+
// 队列中只剩下 1 个元素时就停止数数
131+
while (queue.size() > 1) {
132+
// 不是 number 时,重新加入到队尾
133+
// 是 number 时,将其删除
134+
135+
for (let i = 0; i < number - 1; i++) {
136+
// number 数字之前的人重新放入到队尾(即把队头删除的元素,重新加入到队列中)
137+
queue.enqueue(queue.dequeue());
138+
}
139+
140+
// number 对应这个人,直接从队列中删除
141+
// 由于队列没有像数组一样的下标值不能直接取到某一元素,
142+
// 所以采用,把 number 前面的 number - 1 个元素先删除后添加到队列末尾,
143+
// 这样第 number 个元素就排到了队列的最前面,可以直接使用 dequeue 方法进行删除
144+
queue.dequeue();
145+
}
146+
147+
// 4、获取最后剩下的那个人
148+
const endName = queue.front();
149+
150+
// 5、返回这个人在原数组中对应的索引
151+
return nameList.indexOf(endName);
152+
}
153+
```
154+
155+
#### 测试代码
156+
157+
```js
158+
const names = ["lily", "lucy", "tom", "tony", "jack"];
159+
const targetIndex = passGame(names, 4);
160+
console.log("击鼓传花", names[targetIndex]); //--> lily
161+
```
162+
163+
### 优先队列
164+
165+
优先级队列主要考虑的问题:
166+
167+
- 每个元素不再只是一个数据,还包含数据的优先级。
168+
- 在添加数据过程中,根据优先级放入到正确位置。
169+
170+
#### 优先队列的实现
171+
172+
##### 代码实现
173+
174+
```js
175+
class PriorityQueue {
176+
items = [];
177+
178+
// 内部类
179+
QueueElement = class {
180+
constructor(element, priority) {
181+
this.element = element;
182+
this.priority = priority;
183+
}
184+
};
185+
186+
// enqueue() 入队,将元素按优先级加入到队列中
187+
enqueue(element, priority) {
188+
// 根据传入的元素,创建 QueueElement 对象
189+
const queueElement = new this.QueueElement(element, priority);
190+
191+
// 判断队列是否为空
192+
if (this.isEmpty()) {
193+
// 如果为空,不用判断优先级,直接添加
194+
this.items.push(queueElement);
195+
} else {
196+
// 定义一个变量记录是否成功添加了新元素
197+
let added = false;
198+
199+
for (let i = 0; i < this.items.length; i++) {
200+
// 让新插入的元素进行优先级比较,priority 值越小,优先级越大
201+
if (queueElement.priority < this.items[i].priority) {
202+
// 在指定的位置插入元素
203+
this.items.splice(i, 0, queueElement);
204+
added = true;
205+
break;
206+
}
207+
}
208+
209+
// 如果遍历完所有元素,优先级都大于新插入的元素,就将新插入的元素插入到最后
210+
if (!added) {
211+
this.items.push(queueElement);
212+
}
213+
}
214+
}
215+
216+
// dequeue() 出队,从队列中删除前端元素,返回删除的元素
217+
dequeue() {
218+
return this.items.shift();
219+
}
220+
221+
// front() 查看队列的前端元素
222+
front() {
223+
return this.items[0];
224+
}
225+
226+
// isEmpty() 查看队列是否为空
227+
isEmpty() {
228+
return this.items.length === 0;
229+
}
230+
231+
// size() 查看队列中元素的个数
232+
size() {
233+
return this.items.length;
234+
}
235+
236+
toString() {
237+
let result = "";
238+
for (let item of this.items) {
239+
result += item.element + "-" + item.priority + " ";
240+
}
241+
return result;
242+
}
243+
}
244+
```
245+
246+
#### 测试代码
247+
248+
```js
249+
const priorityQueue = new PriorityQueue();
250+
251+
// 入队
252+
priorityQueue.enqueue("A", 10);
253+
priorityQueue.enqueue("B", 15);
254+
priorityQueue.enqueue("C", 11);
255+
priorityQueue.enqueue("D", 20);
256+
priorityQueue.enqueue("E", 18);
257+
258+
console.log(priorityQueue.items);
259+
//--> output:
260+
// QueueElement {element: "A", priority: 10}
261+
// QueueElement {element: "C", priority: 11}
262+
// QueueElement {element: "B", priority: 15}
263+
// QueueElement {element: "E", priority: 18}
264+
// QueueElement {element: "D", priority: 20}
265+
266+
// 出队
267+
priorityQueue.dequeue();
268+
priorityQueue.dequeue();
269+
console.log(priorityQueue.items);
270+
//--> output:
271+
// QueueElement {element: "B", priority: 15}
272+
// QueueElement {element: "E", priority: 18}
273+
// QueueElement {element: "D", priority: 20}
274+
275+
console.log(priorityQueue.isEmpty()); //--> false
276+
console.log(priorityQueue.size()); //--> 3
277+
console.log(priorityQueue.toString()); //--> B-15 E-18 D-20
278+
```
279+
280+
### 数组、栈和队列图解
281+
![array-stack-queue](https://user-images.githubusercontent.com/24516169/88051118-b02ebd80-cb8a-11ea-9acf-4329cbbff6fc.png)

‎src/PriorityQueue/index.js‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import PriorityQueue from './priorityQueue';
2+
3+
// ----- 优先队列结构测试 -----//
4+
console.log('// ----- 优先队列结构测试 START -----//');
5+
6+
const priorityQueue = new PriorityQueue();
7+
8+
// 入队
9+
priorityQueue.enqueue('A', 10);
10+
priorityQueue.enqueue('B', 15);
11+
priorityQueue.enqueue('C', 11);
12+
priorityQueue.enqueue('D', 20);
13+
priorityQueue.enqueue('E', 18);
14+
15+
console.log(priorityQueue.items);
16+
//--> output:
17+
// QueueElement {element: "A", priority: 10}
18+
// QueueElement {element: "C", priority: 11}
19+
// QueueElement {element: "B", priority: 15}
20+
// QueueElement {element: "E", priority: 18}
21+
// QueueElement {element: "D", priority: 20}
22+
23+
// 出队
24+
priorityQueue.dequeue();
25+
priorityQueue.dequeue();
26+
console.log(priorityQueue.items);
27+
//--> output:
28+
// QueueElement {element: "B", priority: 15}
29+
// QueueElement {element: "E", priority: 18}
30+
// QueueElement {element: "D", priority: 20}
31+
32+
console.log(priorityQueue.isEmpty()); //--> false
33+
console.log(priorityQueue.size()); //--> 3
34+
console.log(priorityQueue.toString()); //--> B-15 E-18 D-20
35+
36+
console.log('// ----- 优先队列结构测试 END -----//');
37+
38+

0 commit comments

Comments
(0)

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