在JavaScript中實現隊列

做爲一個優秀的程序猿須要具備知識的廣度。首先是要了解你選擇的編程語言。若是你正在閱讀這篇文章,最有可能使用 JavaScript。javascript

然而在熟悉了編程語言以後,你還必須瞭解如何根據任務輕鬆且有效地操縱數據。這就是數據結構的用武之地。前端

在本文中,我將描述隊列數據這個結構:它都有哪些操做以及在 JavaScript 中怎樣實現。java

1. 隊列數據結構

若是你喜歡四處旅行,確定在火車站經歷過檢票這道手續。若是有不少人要坐火車,那麼很天然地會造成一個隊列。剛進入車站的人加入隊列。另外一邊剛剛經過檢票的人從隊列中走出。這就是隊列的一個例子,與隊列數據結構的操做方式相同。程序員

隊列是一種遵循先入先出(FIFO)規則的數據結構。第一個進入隊列中的項目(輸入)是第一個出隊(輸出)的。面試

隊列有2個指針:隊首和隊尾。最早進入隊列進行排隊的項目位於隊首,而最後進入隊列的項目位於隊尾編程

回顧車站的例子,第一個檢票的是在隊列的隊首。剛進入隊列的人在隊尾。segmentfault

image.png

從更高的層面來看,隊列是一種容許你按照前後順序處理項目的數據結構。服務器

2. 隊列的操做

隊列支持 2 個主要操做:入隊(enqueue)出隊(dequeue),另外還有 peek 和 length 操做。微信

2.1 入隊操做

入隊操做在隊列的尾部插入項目,使其成爲隊列的隊尾。數據結構

image.png

上圖中的入隊操做在隊尾插入了 8,以後 8 成爲隊列的隊尾。

queue.enqueue(8);

2.2 出隊操做

出隊操做取出隊列中第一個項目,此時隊列中的下一個項目成爲隊首。

image.png

在上圖中,出隊操做返回項目7並從隊列中刪除。 出隊以後以後,項目 2 成爲新的隊首。

queue.dequeue(); // => 7

2.3 Peek 操做

Peek 操做讀取隊首的項目,可是不改變隊列。

image.png

上圖中 7 是隊首。 peek 操做只需返回隊首 7 可是不修改隊列。

queue.peek(); // => 7

2.4 length

length 操做返回隊列中包含項目的數量。

image.png

上圖中的隊列有 4 項:462 和。7。結果隊列長度爲 4

queue.length; // => 4

2.5 隊列操做的時間複雜度

關於隊列全部操做的重點:enqueue,dequeue,peek 和 length 必須以常數時間複雜度 O(1) 執行。

常數時間複雜度 O(1) 意味着不管隊列大小如何(無論是有 10 個仍是 100 萬個項目),這些操做都必須在相對一致的時間內執行。

3. 用 JavaScript 實現隊列

來看一下怎樣在保證全部操做必須以常數時間複雜度O(1) 要求實現隊列這種數據結構。

class Queue {
  constructor() {
    this.items = {};
    this.headIndex = 0;
    this.tailIndex = 0;
  }

  enqueue(item) {
    this.items[this.tailIndex] = item;
    this.tailIndex++;
  }

  dequeue() {
    const item = this.items[this.headIndex];
    delete this.items[this.headIndex];
    this.headIndex++;
    return item;
  }

  peek() {
    return this.items[this.headIndex];
  }

  get length() {
    return this.tailIndex - this.headIndex;
  }
}

const queue = new Queue();

queue.enqueue(7);
queue.enqueue(2);
queue.enqueue(6);
queue.enqueue(4);

queue.dequeue(); // => 7

queue.peek();    // => 2

queue.length;    // => 3

const queue = new Queue() 是建立隊列的實例。

queue.enqueue(7) 方法將 7 存入隊列中。

queue.dequeue() 從隊列中取出一個頭部項目,而 queue.peek() 只讀隊首項。

最後的 Queue.Length 顯示隊列中還有多少個項目。

關於實現:在 Queue 類中,普通對象 this.Items 將隊列的項目經過數值索引保持。 隊首項的索引由 Where.HeadInex 跟蹤,隊尾項由 this.tailIndex 跟蹤。

隊列方法的複雜度

Queuequeue()dequeue()peek()length() 方法中存在:

  • 屬性訪問器(如:this.items[this.headIndex]),
  • 執行算數操做(如:this.headidex++

這些方法的時間複雜度是恆定的時間 O(1)

4. 總結

隊列是一種遵循先入先出(FIFO)規則的的數據結構。

隊列有 2 個主要操做:入隊和出隊。 另外,隊列能夠有輔助操做,例如 peek 和 length。

全部隊列操做都必須以常數時間 O(1) 執行。

挑戰一下:改進 dequeue()peek() 方法,當在空隊列上執行時會拋出錯誤。

173382ede7319973.gif


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章


歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索