js實現資料結構--佇列

陽光下的冷靜發表於2018-11-23

佇列的概念:

佇列是遵循FIFO(First In First Out,先進先出,也稱為先來先服務)原則的一組有序的項。佇列在尾部新增新元素,並在頭部移除元素,佇列的元素也可以是任何型別的。

佇列的特點:

先進先出,最新新增的元素必須排在佇列的末尾,最先移除的元素必須是頭部第一個元素

生活中的佇列:

在電影院, 自助餐廳, 雜貨店收銀臺,我們所排成的隊伍就是佇列,排在第一位的人會先接受服務

js語法定義佇列及佇列的基本方法:

首先是建立一個類來表示一個佇列,從基本的屬性,方法的宣告開始,程式碼如下:

    //宣告棧和棧的屬性和方法
    function Queue() {
        this.items = [];//儲存佇列中元素的陣列
        this.enqueue = enqueue;//進佇列(從尾部進)
        this.dequeue = dequeue;//出佇列(從頭部出)
        this.front = front;//佇列中第一個元素
        this.size = size;//佇列中的元素個數
        this.isEmpty = isEmpty;//判斷佇列中是否有元素
        this.print = print;//列印佇列元素
    }

重寫佇列的相關方法,程式碼如下:

    function enqueue(element) {//進佇列
        this.items.push(element);
    }

    function dequeue() {//出佇列
        return this.items.shift();
    }

    function front() {//檢視佇列頭元素
        return this.items[0];
    }

    function isEmpty() {//佇列判空
        return this.items.length == 0;
    }

    function size() {//檢視佇列內元素個數
        return this.items.length;
    }

    function print() {//列印佇列的所有元素
        return this.items;
    }

使用佇列:

首先我們需要初始化Queue類,然後驗證一下佇列是不是為空(輸出是true,因為棧內沒有新增元素),程式碼如下:

var queue = new Queue();//佇列初始化
    console.log(queue.isEmpty());//輸出true

元素進佇列,程式碼如下:

 queue.enqueue(2);//元素進佇列
 queue.enqueue(3);

檢視佇列的對頭元素,輸出對列的所有元素和佇列內的元素個數,程式碼如下:

    console.log(queue.front());//輸出2
    console.log(queue.size());//輸出2
    console.log(queue.print());//輸出[2,3]

佇列元素出佇列以及佇列判空,程式碼如下:

    queue.dequeue();
    console.log(queue.size());//輸出1
    console.log(queue.isEmpty());//輸出false

佇列的應用:

1 優先佇列:元素的新增和移除是基於優先順序的,一個現實生活中的例子就是機場登機的順序,頭等艙和商務艙乘客的優先順序要高於經濟艙,甚至有些國家,老年人和孕婦(帶小孩的婦女)登機時也享有優先權,還有就是醫院候診室,醫生會優先處理病情比較嚴重的患者等等。

實現一個優先佇列有這兩種選項:設定優先順序,然後正確的新增元素;或者用入列操作新增元素,然後按優先順序移除它們,在我們的例項中會選擇在正確的位置上新增元素,具體程式碼如下:

 //優先佇列方法,優先順序越大,priority值越小
    function priorityQueue() {
        let priorityQueueItems = [];
        this.elelment = element
        this.enqueue = enqueue;
        this.printEle = printEle;

        //優先佇列與預設的佇列的區別是,每一個在優先佇列中的元素除了元素本身還有該元素所對應的優先順序
        function element(name, priority) {
            this.name = name;
            this.priority = priority;
        }

        //元素進佇列,除了將佇列放入佇列尾部,還要將該元素的優先順序儲存起來
        function enqueue(na, pri) {
            let queue_Element = new element(na, pri);
            let added = false;
            /*如果佇列為空就直接將元素放入佇列中,否則就需要比較該元素和其他元素的優先順序,當找到一個比要新增
            * 的元素的priority值更大(優先順序更低)的項時,就把新元素插到它之前(根據這個邏輯,對於優先順序相同,
            * 但是先新增的元素,同意遵循先進先出的原則)
            * */
            for (var i = 0; i < priorityQueueItems.length; i++) {
                if (queue_Element.priority < priorityQueueItems[i].priority) {
                    priorityQueueItems.splice(i, 0, queue_Element);
                    added = true;
                    break;
                }
            }
            //如果要新增的元素的priority的值大於任何已有的元素,就把它新增到佇列的末尾即可
            if (!added) {
                priorityQueueItems.push(queue_Element);
            }
        }

        function printEle() {
            return priorityQueueItems
        }
    }

    let priority_Queue = new priorityQueue();
    priority_Queue.enqueue('John', 2);
    priority_Queue.enqueue('Tom', 1);
    priority_Queue.enqueue('Jack', 1);
    console.log(priority_Queue.printEle());

最後輸出的結果如下圖:

按優先順序排列的佇列

2 迴圈佇列--擊鼓傳花:另一個修改版的佇列實現,就是迴圈佇列。一個簡單的例子就是擊鼓傳花遊戲,該例子中,孩子們圍成一個圓圈,把花傳給旁邊的人。某個時刻傳花停止,這個時候花在誰手裡,誰就退出圓圈結束遊戲,重複這個過程,直到剩下一個孩子,具體程式碼實現如下:

//佇列應用  擊鼓傳花
    function Queue() {
        this.items = [];//儲存佇列中元素的陣列
        this.enqueue = enqueue;//進佇列(從尾部進)
        this.dequeue = dequeue;//出佇列(從頭部出)
        this.size = size;//佇列中的元素個數
    }
    function dequeue() {//出佇列
        return this.items.shift();
    }
    function enqueue(element) {//進佇列
        this.items.push(element);
    }
    function size() {//檢視佇列內元素個數
        return this.items.length;
    }

    function hotPotato (nameList, num) {
        let queue = new Queue();
        for (let i = 0; i < nameList.length; i++ ){
            queue.enqueue(nameList[i]);
        }
        let eliminated ='';
        while (queue.size() > 1){
            for (let j = 0;j <num; j++){
                queue.enqueue(queue.dequeue());
            }
            eliminated = queue.dequeue();
            console.log(eliminated + '在擊鼓傳花遊戲中被淘汰');
        }
        return queue.dequeue();
    }

    let names = ['John','Jack','Camila','Ingrid','Carl'];
    let winner = hotPotato(names,7);
    console.log('The winner is'+ winner);

輸出結果如下圖:

擊鼓傳花遊戲輸出結果

相關文章