簡單說一說數據結構——隊列

上一次我們已經學習了棧。今天我們來說一說隊列。

隊列和棧非常類似,都是非常容易理解的數據結構。隊列是遵循先來先服務原則的一組有序的項。隊列在尾部添加新元素,並從頂部移除元素。

在現實中,最常見的隊列的例子就是排隊:
這裏寫圖片描述

排在前面的會先被服務,不管是什麼服務。概念的東西非常簡單,在這裏就不再多說了。

接下來聲明一些隊列可用的方法:
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,隊列就講到這裏了。有什麼問題歡迎留言,共同討論,共同成長!

下一節聊稍微複雜的鏈表!但我還是要簡單說。

發佈了33 篇原創文章 · 獲贊 19 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章