1.实现队列(enqueue 入队, dequeue 出队, head 返回头, tail 返回尾 size, clear, isEmpty)
class Queue {
constructor() {
this.items = []
}
enQueue(data) {
this.items.push(data)
}
deQueue() {
let deItem = this.items.shift()
return deItem
}
head() {
return this.items[0]
}
tail() {
return this.items[this.items.length - 1]
}
size() {
return this.items.length
}
clear() {
this.items = []
}
isEmpty() {
return this.items.length === 0
}
}
2. 队列常见算法
(1).约瑟夫环
思路:每隔两个删一个,那就是个数%3余数为0的话出队列,否则出队然后入队,即对头变队尾,直到剩下最后一个
// 约瑟夫环 [100 个数每隔两个删一个, 删到末尾继续从头开始, 求最后一个被删除的数是多少?]
function delRing (ringArrs) {
let queue = new Queue()
ringArrs.forEach(item => {
queue.enQueue(item)
})
let index = 0
while (queue.size() > 1) {
// 出队
let deItem = queue.deQueue()
index = index + 1
// 如果不是隔两个则入队
if (index % 3 !== 0) {
queue.enQueue(deItem)
}
}
return queue.head()
}
let ringArrs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let lastOne = delRing(ringArrs)
console.log(lastOne)
(2).斐波那契数列:1、1、2、3、5、8、13、21、34、……
函数实现:
思路:递归,前两个数为1, 其他F(n) = F(n-1) + F(n-2)
function Fibonacci (n , ac1 = 1 , ac2 = 1) {
if( n <= 1 ) {return ac2};
return Fibonacci (n - 1, ac2, ac1 + ac2);
}
队列实现:
思路:前两个数为1, 其他:首先将前两个数1,1入队,然后循环(索引小于n - 2, 因为默认比2大),队列始终有两个数,队头加队尾再入队操作,最后循环完,返回队尾就可
function Fibonacci(n) {
if (n === 1 || n === 2) return 1
let index = 0
let queue = new Queue()
queue.enQueue(1)
queue.enQueue(1)
while (index < n - 2) {
let headItem = queue.deQueue()
let nextItem = queue.head()
let result = headItem + nextItem
queue.enQueue(result)
index = index + 1
}
return queue.tail()
}
(3). 两个队列实现一个栈:
思路:两个指针,dataQueue始终指向有数据的队列,emptyQueue指向空队列。此时top栈顶就是数据队列的队尾;
push就是数据队列的入队;pop数据队列出队到空队列,直到数据队列的长度是1,此时数据队列队尾出队即可
// 两个队列实现一个栈
class QueueToStack {
constructor() {
this.firstQueue = new Queue()
this.secondQueue = new Queue()
this.emptyQueue = null
this.dataQuee = null
}
/**
* 初始化队列,初始化数据队列和空队列的指向
*/
initQueue () {
// 使得数据队列始终指向有数据的队列
if (this.firstQueue.isEmpty()) {
this.dataQuee = this.secondQueue
this.emptyQueue = this.firstQueue
} else {
this.dataQuee = this.firstQueue
this.emptyQueue = this.secondQueue
}
}
pop () {
this.initQueue()
// 弹出栈顶, 在这里其实就是数据栈dataQuee队尾出队
while (this.dataQuee.size() > 1) {
// 数据队列出队到空队列中
this.emptyQueue.enQueue(this.dataQuee.deQueue())
}
// 数据栈dataQuee队尾出队
return this.dataQuee.deQueue()
}
push (data) {
this.initQueue()
this.dataQuee.enQueue(data)
}
top () {
this.initQueue()
return this.dataQuee.tail()
}
}
let queueToStack = new QueueToStack()
queueToStack.push(1)
queueToStack.push(2)
queueToStack.push(3)
queueToStack.push(4)
queueToStack.pop()
queueToStack.pop()
console.log(queueToStack.top())
(4).思考两个栈如何实现一个队列?
思路:根据两个队列实现一个栈
// 两个栈实现一个队列
class StackToQueue {
constructor() {
this.firstStack = new Stack()
this.secondStack = new Stack()
this.dataStack = null
this.emptyStack = null
}
/**
* 初始化栈指向
*/
initStack () {
if (this.firstStack.isEmpty()) {
this.dataStack = this.secondStack
this.emptyStack = this.firstStack
} else {
this.dataStack = this.firstStack
this.emptyStack = this.secondStack
}
}
enQueue (data) {
this.initStack()
// 入队,此处就是向数据栈进栈操作
this.dataStack.push(data)
}
deQueue() {
this.initStack()
// 出队,就是数据栈底
// 1. 数据栈出栈, 空栈入栈
while (this.dataStack.size() > 1) {
//栈从 1, 2, 3 -> 到 3 ,2, 1 转换后,数据栈的栈顶其实就是队列的队头
this.emptyStack.push(this.dataStack.pop())
}
// 2. 循环完毕后, 数据栈只剩栈底,其实就是对头,出栈即可, 1出栈
let popItem = this.dataStack.pop()
// 3. 恢复数据栈,目的是 栈从 3, 2 -> 恢复到 2, 3
while (this.emptyStack.size()) {
this.dataStack.push(this.emptyStack.pop())
}
return popItem
}
head() {
this.initStack()
// 对头其实就是数据栈底
// 1. 数据栈出栈, 空栈入栈
while (this.dataStack.size()) {
//栈从 1, 2, 3 -> 到 3 ,2, 1 转换后,数据栈的栈顶其实就是队列的队头
this.emptyStack.push(this.dataStack.pop())
}
// 2.此时空栈有数据 3 ,2, 1, 返回栈顶1即可
let topItem = this.emptyStack.top()
// 3. 恢复数据栈,目的是 栈从 3, 2, 1 -> 恢复到 1, 2, 3
while (this.emptyStack.size()) {
this.dataStack.push(this.emptyStack.pop())
}
return topItem
}
tail() {
this.initStack()
// 队尾即数据栈顶,直接返回即可
return this.dataStack.top()
}
}
let queueToStack = new StackToQueue()
queueToStack.enQueue(1)
queueToStack.enQueue(2)
queueToStack.enQueue(3)
queueToStack.enQueue(4)
queueToStack.deQueue()
queueToStack.deQueue()
console.log(queueToStack.head())
console.log(queueToStack.tail())
来源:https://blog.csdn.net/davidPan1234/article/details/100008442