浅析JavaScript中的队列和双端队列

什么是队列

队列是遵循先进先出(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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值