# 第5章 队列和双端队列
# 概念
队列是遵循先进先出(FIFO)原则的一组有序的项。队列在尾部添加新元素,并从栈顶移除元素。最新添加的元素必须排在队列的末尾。
双端队列(deque)是一种允许我们同时从前端和后端添加和移除元素的特殊队列。
# 队列对象实现
class Queue {
constructor() {
this.count = 0
this.lowestCount = 0
this.items = {}
}
enqueue(element) {
this.items[this.count] = element
this.count++
}
dequeue() {
if (this.isEmpty()) {
return undefined
}
const result = this.items[this.lowestCount]
delete this.items[this.lowestCount]
this.lowestCount++
return result
}
peek() {
if (this.isEmpty()) {
return undefined
}
return this.items[this.lowestCount]
}
isEmpty() {
return this.size() === 0
}
clear() {
this.items = {}
this.count = 0
this.lowestCount = 0
}
size() {
return this.count - this.lowestCount
}
toString() {
if (this.isEmpty()) {
return ""
}
let objString = `${this.items[this.lowestCount]}`
for (let i = this.lowestCount + 1; i < this.count; i++) {
objString = `${objString},${this.items[i]}`
}
return objString
}
}
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
48
49
50
51
52
53
54
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
48
49
50
51
52
53
54
# 双端队列对象实现
class Deque {
constructor() {
this.count = 0
this.lowestCount = 0
this.items = {}
}
addFront(element) {
if (this.isEmpty()) {
this.addBack(element)
} else if (this.lowestCount > 0) {
this.lowestCount--
this.items[this.lowestCount] = element
} else {
for (let i = this.count; i > 0; i--) {
this.items[i] = this.items[i - 1]
}
this.count++
this.items[0] = element
}
}
addBack(element) {
this.items[this.count] = element
this.count++
}
removeFront() {
if (this.isEmpty()) {
return undefined
}
const result = this.items[this.lowestCount]
delete this.items[this.lowestCount]
this.lowestCount++
return result
}
removeBack() {
if (this.isEmpty()) {
return undefined
}
this.count--
const result = this.items[this.count]
delete this.items[this.count]
return result
}
peekFront() {
if (this.isEmpty()) {
return undefined
}
return this.items[this.lowestCount]
}
peekBack() {
if (this.isEmpty()) {
return undefined
}
return this.items[this.count - 1]
}
isEmpty() {
return this.size() === 0
}
clear() {
this.items = {}
this.count = 0
this.lowestCount = 0
}
size() {
return this.count - this.lowestCount
}
toString() {
if (this.isEmpty()) {
return ""
}
let objString = `${this.items[this.lowestCount]}`
for (let i = this.lowestCount + 1; i < this.count; i++) {
objString = `${objString},${this.items[i]}`
}
return objString
}
}
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 击鼓传花游戏
num 代表传几次,停下来的那个人淘汰。剩最后一个人是胜者。
function hotPotato(elementsList, num) {
const queue = new Queue()
const elimitatedList = []
for (let i = 0; i < elementsList.length; i++) {
queue.enqueue(elementsList[i])
}
while (queue.size() > 1) {
for (let i = 0; i < num; i++) {
queue.enqueue(queue.dequeue())
//从队列开头移除一项,再将其添加到队列末尾
}
elimitatedList.push(queue.dequeue()) //这个人被淘汰,queue.size()减1
}
return {
eliminated: elimitatedList,
winner: queue.dequeue()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 回文检查器
回文是正反都能读通的单词、词组、数或一系列字符的序列,列如 madam 或 racecar.如果只有一个字符的话它肯定是回文。
function palindromeChecker(aString) {
if (aString === undefined || aString === null || (aString !== null && aString.length === 0)) {
return false
}
const deque = new Deque()
const lowerString = aString
.toLocaleLowerCase()
.split(" ")
.join("")
let firstChar
let lastChar
for (let i = 0; i < lowerString.length; i++) {
deque.addBack(lowerString.charAt(i))
}
while (deque.size() > 1) {
firstChar = deque.removeFront()
lastChar = deque.removeBack()
if (firstChar !== lastChar) {
return false
}
}
return true
}
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
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