JavaScript資料結構之-佇列

collins是個愛哭的鼻涕蟲發表於2019-05-01

佇列資料結構

佇列遵循FIFO,先進先出原則的一組有序集合。佇列在尾部新增元素,在頂部刪除元素。在現實中最常見的佇列就是排隊。先排隊的先服務。(請大家文明排隊,不要插隊。

JavaScript資料結構之-佇列

建立佇列

實現包含以下方法的Queue類

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

1、簡單實現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;
    };
}
複製程式碼

2、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);
複製程式碼

JavaScript資料結構之-佇列

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

相關文章