隊列和棧很是的相似,可是他們採用了不一樣的原則,棧採用的是後進先出,隊列正好相反,採用的是先進先出的原則。隊列的定義以下java
隊列是遵循FIFO(先進先出)原則的有序集合,新添加的元素保存在隊列的尾部,要移除的元素保存在隊列的頂部。在隊列的這種數據結構裏面,新增的元素都在尾部,要移除的元素都在頂部。數組
舉一個生活中的例子,在咱們平時去吃肯德基吃飯時確定要排隊,這條隊伍就能夠看作是一個隊列,排在隊伍前面的就是隊列的頂部,隊伍後面的就是隊列的尾部,後來的人都要排在隊伍的後面(隊列的尾部),這就符合了隊列先進先出的原則了(先排隊的能夠先點餐)。網絡
下面用代碼來實現隊列這個數據結構,一樣都採用ES6的語法,咱們先定義一個類Queue
來表示隊列,而後在這個類的基礎上定義一下方法來模擬隊列的行爲。數據結構
class Queue { constructor() { // 定義一個數組來保存隊列裏面的元素 this.items = [] } // 在隊列尾部添加一個或者多個元素 enqueue(element) { } // 移除隊列頂部的元素,並返回被移除的元素 dequeue() { } // 清空隊列 remove() { } // 返回隊列頂部的元素,不對隊列自己作修改 front() { } // 判斷隊列是否爲空 isEmpty() { } // 返回隊列裏面元素的個數 length() { } }
這樣咱們就定義好一個基類了,下面來分別實現隊列的行爲方法this
第一個要實現的就是enqueue方法,這個方法接收一個參數,而後把該參數插入隊列的尾部,由於這裏咱們是用數組來存儲隊列的元素的,因此能夠用數組的push方法來實現該操做,代碼以下線程
enqueue (element) { this.items.push(element) }
下面接着實現dequeue方法,這個方法會從隊列裏面移除項,因爲隊列遵循的是先進先出的原則,因此咱們要移除的元素就是隊列頂部的元素,一樣由於這裏咱們是用數組來存儲隊列的元素的,因此能夠用數組的shift方法來實現該操做。代碼以下調試
dequeue () { return this.items.shift() }
接着來實現remove方法,改方法會移除隊列裏面全部的項,同理咱們把保存隊列元素的數組置空就行了,代碼以下code
remove () { this.items = [] }
上面的方法都是對隊列自己有修改的,接下來要實現的方法front作的是隻讀操做,front方法會返回隊列頂部的元素但不對隊列自己進行修改,代碼實現以下隊列
front () { return this.items[0] }
isEmpty方法判斷隊列是否爲空,也就是保存隊列的數組的長度是否等於0,代碼實現以下ip
isEmpty () { return this.items.length === 0 }
最後一個方法返回隊列的長度,同理就是返回保存隊列元素的數組的長度就行了,代碼以下
length () { return this.item.length }
這裏和棧同樣添加一個輔助方法print
來打印棧裏面的元素,方便咱們觀察調試,這個方法和隊列的行爲無關,只是一個輔助方法
print(){ this.items.forEach((item, index) => { console.log(`${index+1}:${item}`) }) }
這樣隊列的方法就所有寫好了,最後完整Queue
類的代碼以下
class Queue { constructor() { // 定義一個數組來保存隊列裏面的元素 this.items = [] } // 在隊列尾部添加一個或者多個元素 enqueue (element) { this.items.push(element) } // 移除隊列頂部的元素,並返回被移除的元素 dequeue() { return this.items.shift() } // 清空隊列 remove() { this.items = [] } // 返回隊列頂部的元素,不對隊列自己作修改 front() { return this.items[0] } // 判斷隊列是否爲空 isEmpty() { return this.items.length === 0 } // 返回隊列裏面元素的個數 length() { return this.item.length } print(){ this.items.forEach((item, index) => { console.log(`${index+1}:${item}`) }) } }
要使用這個類咱們得先實例化它
const queue = new Queue() queue.isEmpty() // true queue.push('我是隊列的第一個元素') queue.push('我是隊列的第二個元素') queue.print() // 1: 我是隊列的第一個元素 2:我是隊列的第二個元素 queue.dequeue() // 我是隊列的第一個元素 queue.front() // 我是隊列的第二個元素 queue.length() // 1 queue.isEmpty() // false queue.remove() // 這時隊列裏面已經沒有元素了 queue.isEmpty() // true
隊列這種數據結構運用的是很是的普遍的,就好比javaScript的運行機制,咱們都知道javaScript是單線程的,是不能同時執行多個任務,可是單線程就意味着全部任務須要排隊。可是在javaScript裏面,不少時候阻止線程運行的很慢的是網絡IO之類,這時候CPU是空閒的,這樣就會形成資源的浪費。因此javaScript在主線程以外實現了一個任務隊列,像IO之類比較慢的操做暫時都會掛在任務隊列上,這樣不會影響到主線程上任務的執行,等到IO的響應回來後再回到主線程上來執行掛起的任務。例子就是咱們的Ajax請求,定時器等。