02Javascript資料結構與演算法 之 佇列

zhaoyezi發表於2018-08-23

1. 定義

佇列遵循先進先出(FIFO)的原則的一組有序的項。佇列在尾部新增新元素,並在頂部移除元素。最新新增的元素必須排在佇列的末尾。

02Javascript資料結構與演算法 之 佇列

2. 佇列例項

我們使用陣列來儲存資料,然後再為它編寫一些特性的方法:

  • enqueue(elements): 向佇列尾部新增一個(或多個)新的項
  • dequeue(): 移除佇列中的第一項,並返回被移除的元素
  • front(): 返回佇列中中的第一個元素(最先被新增的),佇列不做任何改動
  • isEmpty(): 如果佇列中不包含任何元素,返回true,否則返回false
  • size(): 返回佇列個數
function Queue() {
    var items = [];
    this.enqueue = (item) => {
        if (typeof item === 'number') {
            items.push(item);
        } else {
            items.push(...item);
        }
    };
    this.dequeue = () => (items.shift());
    this.front = () => (items[0]);
    this.isEmpty = () => (items.length === 0);
    this.clear = () => (items = []);
    this.size = () => (items.length);
}

let queue = new Queue();
queue.enqueue([1,2,3]);
console.log(queue.dequeue());
console.log(queue.size());
console.log(queue.isEmpty());
console.log(queue.clear());
console.log(queue.size(), queue.isEmpty());
複製程式碼

Queue類和Stack類非常類似。唯一的區別是dequeue方法和front方法,這是由於先進先出和後進先出原則的不同所造成的。

3. 優先佇列

優先佇列條件要求如下:

  • 同等優先順序,維持先進先出
  • 不同優先順序,1=>6 (或更大), 數字越小,優先順序越高 => 不管誰先進,在出佇列時,數字越小更先出
function Queue() {
    let items = [];
    
    // 一個包含優先順序和值的item類
    function QueueElement(element, priority) {
        this.element = element;
        this.priority = priority; 
    }

    this.enqueue = (element, priority) => {
        var queueElement = new QueueElement(element, priority);
        if (!this.isEmpty()) {
            items.push(queueElement);
        } else {
            let add = false;
            for (let i = 0; i < items.length; i++) {
                if (priority < items[i].priority) {
                    add = true;
                    items.splice(i, 0, queueElement);
                    break;
                }
            }
            // add 為false,代表items中的優先順序都優先於element
            if (!add) {
                items.push(queueElement)
            }
        }
    };
}
複製程式碼

3. 迴圈佇列(丟手絹遊戲)

一群人圍成一個圈, 手絹丟到誰的背後誰就淘汰。那麼利用佇列實現如下:

  • 存放佇列初始化資料(7個人)
  • 經過某個人後面,將該人移除佇列,並放到佇列的最後,達到迴圈的作用
  • 丟到某一個人後面,移除佇列

02Javascript資料結構與演算法 之 佇列

function PlayGames() {

    // 利用佇列來儲存資料
    let queue = new Queue();

    // 初始化資料
    this.setPeople = (people) => (queue.enqueue(people));

    // 每次移除的物件
    this.remove = (removeIndex) => {
        while(queue.size() > 0) {
            for ( let i = 0; i < removeIndex; i++) {
            queue.enqueue(queue.dequeue());
            }
            let eliminated = queue.dequeue();
            console.log(`${eliminated} 被移除了!`, queue.size());
        }
    };
}

var p = new PlayGames();
p.setPeople([1,2,3,4]);
p.remove(7);
複製程式碼

相關文章