原文:
概念:
與棧相反,隊列是一種遵循先進先出 (FIFO / First In First Out) 原則的一組有序的項;隊列在尾部添加新元素,並從頭部移除元素。最新添加的元素必須排在隊列的末尾。在現實中,最常見的例子就是排隊,吃飯排隊、銀行業務排隊、公車的前門上后門下機制...,前面的人優先完成自己的事務,完成之后,下一個人才能繼續。常見的應用形式是視頻網站的緩沖以及打印隊列。
基礎隊列:
class Queue { constructor(items) { this.items = items || []; } // 入列 enqueue(ele) { this.items.push(ele); } // 出列 dequeue() { this.items.shift(); } // front() { return this.items[0]; } clear() { this.items = []; } get size() { return this.items.length; } get isEmpty() { return !this.items.length; } print() { console.log(this.items.toString()); } } let queue = new Queue() console.log(queue.isEmpty) // true queue.enqueue('John') queue.enqueue('Jack') queue.enqueue('Camila') console.log(queue.size) // 3 console.log(queue.isEmpty) // false queue.dequeue() queue.dequeue() queue.print() // 'Camila'
優先隊列:
如醫院的急診,雖然都有專門的急診科,但是就理解而言嚴重程度高的可以先就診。優先隊列可以根據優先級進行排列。
實現思路也簡單,普通隊列直接 push 元素,那么優先隊列就是插入包含優先級的對象,插入前先進行優先級驗證,在相應位置插入元素。
下例實現根據優先級插入數據,出列操作同普通隊列。
class PriorityQueue { constructor() { this.items = []; } get isEmpty() { return !this.items.length; } get size() { return this.items.length; } enqueue(ele, priority) { let queueEle = { ele, priority }; if (this.isEmpty) { this.items.push(queueEle); } else { let preIndex = this.items.findIndex(item => queueEle.priority < item.priority); if (preIndex > -1) { this.items.splice(preIndex, 0, queueEle); } else { this.items.push(queueEle); } } } dequeue() { return this.items.shift(); } front() { return this.items[0]; } clear() { this.items = []; } print() { console.log(this.items) } } let priorityQueue = new PriorityQueue() priorityQueue.enqueue('John', 2) priorityQueue.enqueue('Jack', 1) priorityQueue.enqueue('Camila', 1) priorityQueue.enqueue('Surmon', 3) priorityQueue.enqueue('skyRover', 2) priorityQueue.enqueue('司馬萌', 1) priorityQueue.print() console.log(priorityQueue.isEmpty, priorityQueue.size) // false 6
循環隊列:
循環隊列在概念上就是將隊尾和隊首閉環。
為充分利用向量空間,克服"假溢出"現象的方法是:將向量空間想象為一個首尾相接的圓環,並稱這種向量為循環向量。存儲在其中的隊列稱為循環隊列(Circular Queue)。這種循環隊列可以以單鏈表的方式來在實際編程應用中來實現。
js 實現的循環隊列:(基於普通隊列)
class Queue { constructor(items) { this.items = items || []; } // 入列 enqueue(ele) { this.items.push(ele); } // 出列 dequeue() { this.items.shift(); } // front() { return this.items[0]; } clear() { this.items = []; } get size() { return this.items.length; } get isEmpty() { return !this.items.length; } print() { console.log(this.items.toString()); } } class LoopQueue extends Queue { constructor(items) { super(items) } getIndex(index) { let length = this.items.length; return index > length ? index % length : index; } findIndex(index) { return !this.isEmpty ? this.items[this.getIndex(index)] : null; } } const loopQueue = new LoopQueue(['Surmon']) loopQueue.enqueue('SkyRover') loopQueue.enqueue('Even') loopQueue.enqueue('Alice') console.log(loopQueue.size, loopQueue.isEmpty) // 4 false console.log(loopQueue.find(26)) // 'Evan' console.log(loopQueue.find(87651)) // 'Alice'