JS实现队列
队列是一种先进先出(FIFO)的数据结构。通常用来描述算法或生活中的一些先进先出的场景,比如:
- 在 JavaScript 事件循环(Event Loop)中有一个事件队列(Task Queue)处理各种异步事件。
- 现实中排队相关场景。
class Queue {
// queue 用于记录数组,
let queue = []
// 入队
this.enqueue = function (element) {
queue.push(element)
}
// 出队
this.dequeue = function () {
return queue.shift()
}
// 查看队列的第一个元素
this.front = function () {
return queue[0]
}
// 查看队列是否为空
this.isEmpty = function () {
return queue.length == 0
}
// 查看队列的长度
this.size = function () {
return queue.length
}
// 将数组转为字符串并放回
this.toString = function () {
return queue.toString()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 优先队列(权重与插队)
普通的队列类就是调用原生 Array 对象的方法,比较简单,还有一种队列叫优先队列。现实生活中去医院排队,如果大家都死板的按照顺序排队,新来一个车祸重伤员,1 小时内不治疗就会死,很明显医院应该优先医治这个重伤患者。在优先队列里,使用优先级(priority)来描述严重程度。
class PriorityQueue {
let queue = []
// 利用构造器函数创建队列元素
let QueueElement = function(element, priority) {
this.element = element
this.priority = priority
}
this.enqueue = function(element, priority) {
let queueElement = new QueueElement(element, priority)
// 张三的情况
if (this.isEmpty()) {
queue.push(queueElement)
} else {
let added = false
for (let i = 0; i < queue.length; i++) {
if (queueElement.priority < queue[i].priority) {
queue.splice(i, 0, queueElement)
added = true
break
}
}
// 王五的情况
if (!added) {
queue.push(queueElement)
}
}
}
// ... 其它方法与普通队列相同
// 打印这个队列成员时 加上优先级信息
this.toString = function() {
let string = ''
for (let i = 0; i < queue.length; i++) {
string +=
queue[i].element +
'-' +
queue[i].priority +
(queue.length - i > 1 ? ',' : '')
}
return string
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 应用:击鼓传花游戏
规则与实现过程
- 利用队列类,创建一个队列。
- 把当前玩击鼓传花游戏的所有人都放进队列。
- 给定一个数字,迭代队列,从队列的开头移除一项,添加到队列的尾部(如游戏就是:你把花传给旁边的人,你就可以安全了)。
- 一旦迭代次数到达,那么这时拿着花的这个人就会被淘汰。
- 最后剩下一个人,这个人就是胜利者。
// 循环队列(击鼓传花)
function hotPotato(nameList, num) {
let queue = new Queue() //{1} //
for (let i = 0; i < nameList.length; i++) {
queue.enqueue(nameList[i]) // {2}
}
let current = ''
while (queue.size() > 1) {
// 把队列num之前的项按照优先级添加到队列的后面
for (let i = 0; i < num; i++) {
queue.enqueue(queue.dequeue()) // {3}
}
current = queue.dequeue() // {4}
console.log(current + '在击鼓传花游戏中被淘汰')
}
return queue.dequeue() // {5}
}
let names = ['John', 'Jack', 'rose', 'xiaoMing', 'Baobo']
let winner = hotPotato(names, 7)
console.log('获胜者是:' + winner)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
上次更新: 2023/04/05, 09:41:10