javascript資料結構與演算法-佇列

GoodLiang發表於2018-11-17

定義

佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列中沒有元素時,稱為空佇列。 佇列的資料元素又稱為佇列元素。在佇列中插入一個佇列元素稱為入隊,從佇列中刪除一個佇列元素稱為出隊。因為佇列只允許在一端插入,在另一端刪除,所以只有最早進入佇列的元素才能最先從佇列中刪除,故佇列又稱為先進先出(FIFO—first in first out)線性表。

方法和屬性

  • push方法 入隊
  • shift方法 刪除隊頭的元素
  • peek方法 檢視當前隊頭的元素
  • isEmpty方法 檢視佇列是否為空
  • length屬性 佇列的元素個數
  • list屬性 儲存佇列

程式碼實現

這裡依然用js的陣列模擬佇列,畢竟高階語言(落淚),陣列的shift時刪除陣列的第一個元素,這裡list還是公用的

class Queue{
	constructor(){
	    this.list=[];
	    this.length=0;
	}

	/* 入隊 */
	enquequ(value){
	    this.length++;
	    this.list.push(value);
	}

	/* 出隊 */
	dequeue() {
	    if (this.length === 0) return;
	    this.length--;
	    return this.list.shift();
	}
	/* 檢視隊頭 */
	peek() {
	    return this.list[0];
  }
	/* 檢視隊頭 */
	isEmpty(){
	    return this.length ===0;
	}
}
複製程式碼

優先佇列

簡單來說,比方說我是會員,我就要排在你的前面,hhhhhh

實現一個優先佇列,有兩種選項:設定優先順序,然後在正確位置新增元素;或者用入列操作新增元素,然後按照優先順序移除他們。

function PriorityQueue(){
	let items = [];
	// 輔助類
	function QueueElement(element,priority){
	    this.element = element;
	    this.priority = priority;
	}
	this.enquequ=function(element,priority){
	    let queueElement = new QueueElement(element,priority);
	    let added =false;
	    // 比較優先順序
	    for (let i = 0; i < items.length; i++) {
	    // 如果說我的優先順序比較大
	        if(queueElement.priority>items[i].priority){
	            // 陣列切割,實現新增操作
	            items.splice(i,0,queueElement);
	            added=true;
	            break;
	        }
	    }
	    // 如果沒有插入就是說我的優先順序都比他們小,就放到隊尾
	    if(!added){
	        items.push(queueElement);
	    }
	};
	// 列印
	this.print=function(){
	    for (let i = 0; i < items.length; i++) {
	        console.log(`${items[i].element}- ${items[i].priority}`);
	    }
	}
}
let priorityQueue = new PriorityQueue();
priorityQueue.enquequ("skl",2);
priorityQueue.enquequ("skl2",1);
priorityQueue.enquequ("skl3",3);
priorityQueue.print();
複製程式碼

如果佇列為空,就直接插入,如果不為空,就進行優先順序比較操作。中間使用了一個輔助類,用來建立名字和優先順序的物件

{
  element:'skl',
  priority:'1',
}
複製程式碼

實現擊鼓傳花

不懂得網上百度一下啥事擊鼓傳花

function hotPotato(nameList,num){
	let queue = new Queue();
	// 先入隊
	for (let i = 0; i < nameList.length; i++) {
	    queue.enquequ(nameList[i]);
	}
	// 被淘汰者
	let eliminated="";
	while(queue.length>1){
	    for (let i = 0; i < num.length; i++) {
	        // 出隊後入隊,就是從隊頭到隊尾去
	        queue.enquequ(queue.dequeue());
	    }
	    // 等於num的那個被淘汰
	    eliminated=queue.dequeue();
	    console.log(eliminated+"在擊鼓傳花中淘汰");
	}
	// 迴圈結束後只有一個人的時候他就是獲勝者了
	return queue.dequeue();
}
let names = ["John","Jack","Camilia","Ingrid","Carl"];
let winner = hotPotato(names,2);
console.log("獲勝者是"+winner);
複製程式碼

輸出過程

John在擊鼓傳花中淘汰
Jack在擊鼓傳花中淘汰
Camilia在擊鼓傳花中淘汰
Ingrid在擊鼓傳花中淘汰
獲勝者是Carl
複製程式碼

下圖模擬了這個過程

javascript資料結構與演算法-佇列

相關文章