上一次我們已經學習了棧。今天我們來說一說隊列。
隊列和棧非常類似,都是非常容易理解的數據結構。隊列是遵循先來先服務原則的一組有序的項。隊列在尾部添加新元素,並從頂部移除元素。
在現實中,最常見的隊列的例子就是排隊:
排在前面的會先被服務,不管是什麼服務。概念的東西非常簡單,在這裏就不再多說了。
接下來聲明一些隊列可用的方法:
enqueue(elements):向隊列尾部添加一個或多個新的項。
dequeue():移除隊列的第一項,並返回被移除的元素。
front():返回隊列中的第一項,隊列不做任何改動。注意與dequeue的區別。
isEmpty():如果隊列中不包含任何元素,返回true,否則返回false。
size():返回隊列中包含的元素個數。
實現代碼:
function Queue(){
var items = [];
this.enqueue = function(element){
items.push(element);
}
this.dequeue = function(){
return items.shift();
}
this.front = function(){
return items[0];
}
this.isEmpty = function(){
return items.length === 0;
}
this.clear = function(){
items = [];
}
this.size = function(){
return items.length;
}
this.print = function(){
console.log(items.toString());
}
}
隊列有兩個修改版,其一是優先隊列。元素的操作是基於優先級的。現實中也有這樣的例子,比如機場登機的順序。頭等艙和商務艙的優先級是要高於經濟艙的;又或者醫院總是會看病情比較嚴重的患者。
如何實現呢?設置優先級。
function PriorityQueue(){
var items = [];
function QueueElement(element , priority){ //聲明一個包含元素和優先級的構造函數
this.element = element;
this.priority = priority;
}
this.enqueue = function(element , priority){
var queueElement = new QueueElement(element , priority);
if(this.isEmpty()){ //如果爲空,直接入列
items.push(queueElement);
}else{
var added = false;
for(var 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);
}
}
}
}
}
其二是循環隊列,現實生活中的例子有擊鼓傳花的遊戲。在這個遊戲中,孩子們圍成一個圓圈,把花儘快地傳遞到旁邊的人。某一時刻鼓聲停止,就停止傳遞。花在誰手上,誰就退出圓圈遊戲。直到只剩下一個孩子。實現起來也是比較簡單的:
function hotPotato(nameList , num){
var queue = new Queue();
for(var i = 0 ; i < nameList.length ; i++){ //把全部人加入到隊列中
queue.enqueue(nameList[i]);
}
var eliminated = '';
while(queue.size() > 1){
for(var i = 0 ; i < num ; i++){ //循環
queue.enqueue(queue.dequeue());
}
eliminated = queue.dequeue(); //到達傳遞次數,淘汰
console.log(eliminated + '被淘汰');
}
return queue.dequeue(); //最後一個勝利者
}
可以看到,不管是優先隊列還是循環隊列,都是基於Queue這個構造函數的。測試代碼請移步到隊列
OK,隊列就講到這裏了。有什麼問題歡迎留言,共同討論,共同成長!
下一節聊稍微複雜的鏈表!但我還是要簡單說。