队列
- 队列
- 双端队列数据结构
- 应用
- 用击鼓传花游戏模拟循环队列
- 用双端对列检查一个词是否构成回文
- 生成 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
JS,双端队列,JS,,队列
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼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]