DDR爱好者之家 Design By 杰米
队列
- 队列
- 双端队列数据结构
- 应用
- 用击鼓传花游戏模拟循环队列
- 用双端对列检查一个词是否构成回文
- 生成 1 到 n 的二进制数
队列和双端队列
队列遵循先进后出(FIFO, 也称为先来先服务) 原则的. 日常有很多这样场景: 排队购票、银行排队等.
由对列的特性,银行排队为例, 队列应该包含如下基本操作:
- 加入队列(取号) enqueue
- 从队列中移除(办理业务离开) dequeue
- 当前排队号码(呼叫下一个人) peek
- 当前队列长度(当前排队人数) size
- 判断队列是不是空 isEmpty
class Queue {
constructor() {
// 队列长度, 类数组 length
this.count = 0
// 队列中所有项
this.items = {}
// 记录对列头, 类数组 index
this.lowestCount = 0
}
enqueue(ele) {
this.items[this.count++] = ele
}
dequeue() {
if (this.isEnpty()) {
return undefined
}
const ele = this.items[this.lowestCount]
delete this.items[this.lowestCount]
this.lowestCount++
return ele
}
peek() {
if (this.isEnpty()) {
return
}
return this.items[this.lowestCount]
}
size() {
/**
* 当队列为非空时:
* 1. count 是长度
* 2. lowestCount 是下标
* 两者关系应该 lowestCount = count - 1
*/
return this.count - this.lowestCount
}
isEnpty() {
return this.size() == 0
}
clear() {
this.items = {}
this.lowestCount = 0
this.count = 0
}
toString() {
if (this.isEnpty()) {
return ''
}
let objString = `${this.items[this.lowestCount]}`
for (let i = this.lowestCount + 1; i < this.count; i++) {
objString = `${objString}, ${this.items[i]}`
}
return objString
}
}
双端队列(deque 或 double-ended queue)
什么是双端队列"htmlcode">
constructor() {
this.items = {}
this.count = 0
this.lowestCount = 0
}
addFront(ele) {
if (this.isEmpty()) {
this.items[this.count] = ele
} else if (this.lowestCount > 0) {
this.lowestCount -= 1
this.items[this.lowestCount] = ele
} else {
for (let i = this.count; i > 0; i--) {
this.items[i] = this.items[i - 1]
}
this.items[0] = ele
}
this.count++
return ele
}
removeFront() {
if (this.isEmpty()) {
return
}
const delEle = this.items[this.lowestCount]
delete this.items[this.lowestCount]
this.lowestCount++
return delEle
}
addBack(ele) {
this.items[this.count] = ele
this.count++
}
removeBack() {
if (this.isEmpty()) {
return
}
const delEle = this.items[this.count - 1]
delete this.items[this.count - 1]
this.count--
return delEle
}
peekFront() {
if (this.isEmpty()) {
return
}
return this.items[this.lowestCount]
}
peekBack() {
if (this.isEmpty()) {
return
}
return this.items[this.count - 1]
}
size() {
return this.count - this.lowestCount
}
isEmpty() {
return this.size() === 0
}
clear() {
this.items = {}
this.count = 0
this.lowestCount = 0
}
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
}
}
队列的应用
击鼓传花游戏
击鼓传花游戏: 简单描述就是一群人围成一个圈传递花,喊停的时花在谁手上就将被淘汰(每个人都可能在前端,每个参与者在队列位置会不断变化),最后只剩下一个时就是赢者. 更加详细可以自行查阅.
下面通过代码实现:
function hotPotato(elementsList, num) {
// 创建一个容器
const queue = new Queue()
const elimitatedList = []
// 把元素(参赛者)加入队列中
for (let i = 0, len = elementsList.length; i < len; i++) {
queue.enqueue(elementsList[i])
}
/**
* 击鼓传花
* 首先队列规则: 先进先出
* 那么在传花过程中,任何一个元素都可能是前端, 在传花的过程中应该就是前端位置不断变化.
* 当喊停的时(num 循环完), 也就是花落在谁手(谁在前端)则会被淘汰*(移除队列)
*/
while (queue.size() > 1) {
for (let j = 0; j < num; j++) {
queue.enqueue(queue.dequeue())
}
elimitatedList.push(queue.dequeue())
}
return {
winer: queue.dequeue(),
elimitatedList
}
}
代码运行如下:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(hotPotato(arr, Math.ceil(Math.random() * 10))) // { winer: 5, elimitatedList: [4, 8, 2, 7, 3,10, 9, 1, 6]}
console.log(hotPotato(arr, Math.ceil(Math.random() * 10))) // { winer: 5, elimitatedList: [4, 8, 2, 7, 3,10, 9, 1, 6]}
console.log(hotPotato(arr, Math.ceil(Math.random() * 10))) // { winer: 8, elimitatedList: [10, 1, 3, 6, 2,9, 5, 7, 4]}
判断回文
上一篇栈中也有涉及回文的实现, 下面我们通过双端队列来实现同样的功能.
function palindromeChecker(aString) {
if (!aString || typeof aString !== 'string' || !aString.trim().length) {
return false
}
const deque = new Deque()
const lowerString = aString.toLowerCase().split(' ').join('')
// 加入队列
for (let i = 0; i < lowerString.length; i++) {
deque.addBack(lowerString[i])
}
let isEqual = true
let firstChar = ''
let lastChar = ''
while (deque.size() > 1 && isEqual) {
firstChar = deque.removeFront()
lastChar = deque.removeBack()
if (firstChar != lastChar) {
isEqual = false
}
}
return isEqual
}
下面通过代码演示下:
console.log(palindromeChecker('abcba')) // true 当前为回文
生成 1 到 n 的二进制数
function generatePrintBinary(n) {
var q = new Queue()
q.enqueue('1')
while (n-- > 0) {
var s1 = q.peek()
q.dequeue()
console.log(s1)
var s2 = s1
q.enqueue(s1 + '0')
q.enqueue(s2 + '1')
}
}
generatePrintBinary(5) // => 1 10 11 100 101
DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米
暂无评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
2025年10月28日
2025年10月28日
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
