JavaScript數據結構之-隊列

隊列數據結構

隊列遵循FIFO,先進先出原則的一組有序集合。隊列在尾部添加元素,在頂部刪除元素。在現實中最多見的隊列就是排隊。先排隊的先服務。(請你們文明排隊,不要插隊。安全

建立隊列

實現包含如下方法的Queue類bash

  • enqueue(element(s)):向隊列尾部添加一個(或多個)元素。
  • dequeue():移除隊列的第一項,並返回移除的元素。
  • front():返回隊列的第一個元素--最早被添加,最早被移除的元素。
  • isEmpty():判斷隊列是否爲空。
  • size():返回隊列的長度。

一、簡單實現Queue類數據結構

// 隊列Queue類簡單實現
function Queue() {
    let 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.size = function() {
        return items.length;
    };
}
複製代碼

二、ES6語法實現Queue隊列類,利用WeakMap來保存私有屬性items,並用外層函數(閉包)來封裝Queue類。閉包

let Queue1 = (function() {
    const items = new WeakMap();
    class Queue1 {
        constructor() {
            items.set(this, []);
        }
        // 獲取隊列
        getQueue() {
            return items.get(this);
        }
        // 添加元素
        enqueue (element) {
            this.getQueue().push(element);
        }
        // 刪除元素
        dequeue() {
            return this.getQueue().shift();
        }
        // 返回隊列第一個元素
        front() {
            return this.getQueue()[0];
        }
        // 判斷隊列是否爲空
        isEmpty() {
            return this.getQueue().length === 0;
        }
        // 返回隊列長度
        size() {
            return this.getQueue().length;
        }
    }
    return Queue1;
})();
複製代碼

優先隊列

元素的添加和刪除基於優先級。常見的就是機場的登機順序。頭等艙和商務艙的優先級高於經濟艙。實現優先隊列,設置優先級。函數

// 優先列隊
function PriorityQueue() {
    let items = [];
    // 建立元素和它的優先級(priority越大優先級越低)
    function QueueElement(element, priority) {
        this.element = element;
        this.priority = priority;
    }
    // 添加元素(根據優先級添加)
    this.enqueue = 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.dequeue = function() {
        return items.shift();
    };
    // 返回隊列第一個元素
    this.front = function() {
        return items[0];
    };
    // 判斷隊列是否爲空
    this.isEmpty = function() {
        return items.length === 0;
    };
    // 返回隊列長度
    this.size = function() {
        return items.length
    };
    // 打印隊列
    this.print = function() {
        for (let i = 0; i < items.length; i++) {
            console.log(`${items[i].element} - ${items[i].priority}`);
        }
    };
}
複製代碼

循環隊列(擊鼓傳花)

// 循環隊列(擊鼓傳花)
function hotPotato(nameList, num) {
    let queue = new Queue(); // {1}
    for(let i =0; i< nameList.length; i++) {
        queue.enqueue(nameList[i]); // {2}
    }
    let eliminted = '';
    while(queue.size() > 1) {
        // 把隊列num以前的項按照優先級添加到隊列的後面
        for(let i = 0; i < num; i++) {
            queue.enqueue(queue.dequeue()); // {3}
        }
        eliminted = queue.dequeue(); // {4}
        console.log(eliminted + '在擊鼓傳花遊戲中被淘汰');
    }
    return queue.dequeue(); // {5}
}
let names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl'];
let winner = hotPotato(names, 7);
console.log('獲勝者是:' + winner);
複製代碼

實現一個模擬擊鼓傳花的遊戲,{1}利用隊列類,建立一個隊列。{2}把當前玩擊鼓傳花遊戲的全部人都放進隊列。{3}給定一個數字,迭代隊列,從隊列的開頭移除一項,添加到隊列的尾部(如遊戲就是:你把花傳給旁邊的人,你就能夠安全了)。{4}一旦迭代次數到達,那麼這時拿着花的這我的就會被淘汰。{5}最後剩下一我的,這我的就是勝利者。ui

相關文章
相關標籤/搜索