什么是队列
队列是遵循先进先出(FIFO)原则的一组有序的项。队列在尾部添加元素,并从首部移除元素。最常见的例子就是食堂排队打饭、电影院排队买票等。
队列的常规操作
第一步:创建队列
class Queue {
constructor () {
this.count = 0 // 队列中元素的总数
this.lowestCount = 0; // 队尾的编号
this.items = {} // 使用对象存放队列 {0:e1, 1:e2...}
}
}
第二步:队列的常用方法:
class Queue {
constructor () {
this.count = 0 // 队列中元素的总数
this.lowestCount = 0; // 队首的编号
this.items = {} // 使用对象存放队列 {0:e1, 1:e2...}
}
enqueue(element) { // 入队操作-从队尾追加数据
this.items[this.count++] = element
}
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.count - this.lowestCount === 0
}
size () { // 返回队列的元素总数
return this.count - this.lowestCount
}
clear () { // 清空队列
this.items = []
this.count = this.lowestCount = 0
}
toString() { // 拼接队列元素为字符串
if (this.isEmpty()) {
return ''
}
let objString = `${this.items[this.lowestCount]}`
for (let i = lowestCount + 1; i < count; i++) {
objString = `${objString}, ${this.items[i]}`
}
return objString
}
}
第三步:使用队列
const queue = new Queue()
queue.enqueue('John')
queue.enqueue('Jack')
console.log(queue) // John,Jack
queue.enqueue('Camila')
console.log(queue.toString()) // John,Jack,Camila
console.log(queue.size()) // 3
queue.dequeue() // 移除John
queue.dequeue() // 移除Jack
双端队列的数据结构
双端队列(deque)是一种可以同时从前端和后端(也就是所谓的队首和队尾)添加和移除元素的特殊队列。
创建一个双端队列:
class Deque {
constructor () {
this.count = 0
this.lowestCount = 0
this.items = {}
}
}
这个结构和队列的创建结构是一样的,也就是说明双端队列是基于队列模式的(只是多了一些方法而已)。
具体看下方法:
class Deque {
constructor () {
this.count = 0 // 队列中元素的总数
this.lowestCount = 0; // 队首的编号
this.items = {} // 使用对象存放队列 {0:e1, 1:e2...}
}
addFront(element) { // 入队操作-从队首添加数据
if (this.isEmtpy()) {
this.addBack(element)
} else if (this.lowestCount > 0 ) {
this.items[--this.lowestCount] = element
} else {
for (let i = this.count; i > 0; --i) {
this.items[i] = this.items[i-1]
}
this.count++
this.lowestCount = 0
this.items[0] = element
}
}
addBack (element) { // 入队操作,在队尾追加元素
this.items[this.count++] = element
}
removeFront () { // 出队操作,从队首弹出元素
if (this.isEmpty()) {
return undefined
}
const s = this.items[this.lowestCount]
delete this.items[this.lowestCount]
this.lowestCount++
return s
}
removeBack () { // 出队操作,从队尾弹出元素
if (this.isEmpty()) {
return undefined
}
const s = this.items[this.count - 1]
delete this.items[this.count - 1]
this.count--
return s
}
peek () { // 查看队首元素
if (this.isEmpty()) {
return undefined
}
return this.items[this.lowestCount]
}
isEmpty () { // 判断队列是否为空
return this.count - this.lowestCount === 0
}
size () { // 返回队列的元素总数
return this.count - this.lowestCount
}
clear () { // 清空队列
this.items = []
this.count = this.lowestCount = 0
}
toString() { // 拼接队列元素为字符串
if (this.isEmpty()) {
return ''
}
let objString = `${this.items[this.lowestCount]}`
for (let i = lowestCount + 1; i < count; i++) {
objString = `${objString}, ${this.items[i]}`
}
return objString
}
}
使用示例:
const deque = new Deque()
console.log(deque.isEmpty() // true
deque.addBack('John')
deque.addBack('Jack')
console.log(deque.toString()) // John, Jack
deque.addFront('Camila')
console.log(deque.toString()) // Camila, John, Jack
console.log(deque.size()) // 3
deque.removeBack() // Camila, John
回文检查器
代码如下:
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 isEqual = true
let firstChar, lastChar
for (let i = 0;i < lowerString.length;i++) {
deque.addBack(lowerString.charAt(i))
}
while(dqueue.size() > 1 && isEqual ) {
firstChar = deque.removeFront()
lastChar = deque.removeBack()
if (firstChar !== lastChar) {
isEqual = false
}
}
return isEqual
}
console.log('a', palindromeChecker('a')) // true
console.log('level', palindromeChecker('level')) // true