一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情。
前言
上次我们实现了一个队列的进阶——双端队列类,本期我们来实现队列的进阶2——循环队列。按照惯例,我们先来介绍一下,什么是循环队列。
定义
为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。——百度百科
方法
- push() 在队尾添加一个元素
- pop() 移除队头元素,同时将队头元素添加至对尾,并返回队头元素
- top() 返回队头元素,不改变队列
- isNull() 判断队列是否为空
- claer() 清空队列
- size() 队列中剩余元素个数
编码实现
创建类
class CircularQueue{
constructor(){
this.items = {}
this.end = 0
this.start = 0
}
}
push()
push(data){
this.items[this.end] = data
this.end++
}
pop()
pop(){
if(this.isNull()){
return undefined
}
const result = this.items[this.start]
// 往队尾添加出队元素
this.push(result)
delete this.items[this.start]
this.start++
return result
}
top()
top(){
return this.items[this.start]
}
isNull()
isNull(){
return this.end - this.start === 0
}
clear()
clear(){
this.items = {}
this.end = 0
this.start = 0
}
size()
size(){
return this.end - this.start
}
完整代码如下:
class CircularQueue {
constructor(){
this.items = {}
this.end = 0
this.start = 0
}
push(data){
this.items[this.end] = data
this.end++
}
pop(){
if(this.isNull()){
return undefined
}
const result = this.items[this.start]
this.push(result)
delete this.items[this.start]
this.start++
return result
}
top(){
return this.items[this.start]
}
isNull(){
return this.end - this.start === 0
}
clear(){
this.items = {}
this.end = 0
this.start = 0
}
size(){
return this.end - this.start
}
}
const cQueue = new CircularQueue()
console.log(cQueue.isNull());// true
cQueue.push(1)
cQueue.push(2)
cQueue.push(3)
cQueue.push(4)
cQueue.push(5)
console.log(cQueue.top());// 1
console.log(cQueue.size());// 5
cQueue.pop()
console.log(cQueue.top());// 2
console.log(cQueue.size());// 5
cQueue.pop()
console.log(cQueue.top());// 3
console.log(cQueue.size());// 5
console.log(cQueue.isNull());// false
cQueue.clear()
console.log(cQueue.isNull());// true
总结
至此,我们实现了队列以及其进阶的数据结构,可以发现,万变不离其宗,除了个别的方法,大多数都是通用的。这样也就看得出,其实队列的进阶:双端队列,循环队列也没有多么难。只要掌握好了基础,进阶也是水到渠成的事。