JavaScript資料結構之佇列

2021-09-12 19:38:15 字數 3278 閱讀 1287

接上篇-資料結構之棧

資料結構之---佇列

1.佇列的定義

佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(end)進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊首。

佇列的資料元素又稱為佇列元素。在佇列中插入乙個佇列元素稱為入隊,從佇列中刪除乙個佇列元素稱為出隊。因為佇列只允許在一端插入,在另一端刪除,所以只有最早進入佇列的元素才能最先從佇列中刪除,故佇列的特性為先進先出(first-in-first-out,fifo)

請看下面的**

佇列新增新的元素,左側是佇列的頭部,右側是佇列的尾部,新的元素如果想進入佇列,只能從尾部進入。

佇列移除元素,左側是佇列的頭部,右側是佇列的尾部, 如果想要出佇列,只能從佇列的頭部出去

日常生活中,排隊就是典型的佇列結構,先到的先被服務,後來的在隊尾等著,直到輪到他為止(當然,特殊情況除外)。比如說其他場景 提交作業系統執行的一系列程序、列印任務池等,一些**系統用佇列來模擬銀行或雜貨 店裡排隊的顧客。

2.佇列的實現

從資料儲存的角度看,實現佇列有兩種方式,一種是以陣列做基礎,一種是以鍊錶做基礎,陣列是最簡單的實現方式,本文以基礎的陣列來實現佇列。

佇列的操作包括建立佇列、銷毀佇列、入隊、出隊、清空佇列、獲取隊頭元素、獲取佇列的長度。

我們定義以下幾個佇列的方法:

然後我們利用es6的class的實現以上的方法 新建乙個queue.js檔案

class queue 

enqueue(item)

dequeue()

head()

tail()

size()

isempty()

clear()

}複製**

3.佇列的應用

記住兩點:

3.1 約瑟夫環問題

有乙個陣列存放了100個資料0-99,要求每隔兩個數刪除乙個數,到末尾時再迴圈至開頭繼續進行,求最後乙個被刪除的數字。

比如說:有十個數字:0,1,2,3,4,5,6,8,9,每隔兩個數刪除乙個數,就是2 5 8 刪除,如果只是從0到99每兩個數刪除乙個數,其實挺簡單的,但是我們還得考慮到末尾的時候還有再重頭開始,還得考慮刪除掉的元素從陣列中刪除。那我們如果佇列的話,就比較簡單了

3.1.2 思路分析

經過while迴圈後,不斷的有元素出佇列,最後隊伍中只會剩下乙個被刪除的元素

3.1.3 看**實現

// 每隔兩個數刪除乙個數

function delrang(arr)

var index = 0;

while (queue.size() !== 1)

}console.log(queue.head()); // 90

return queue.head(); // 返回最後乙個元素

}delrang(arr);

}複製**

是不是感覺使用佇列很簡單呢,接下來再看幾個小練習

3.2 斐波那契數列

3.2.1 題目介紹

3.2.2 我們先考慮使用普通的方法實現 -- 遞迴 遞迴版 **實現

function fibonacci (n) ;

return fibonacci(n - 1) + fibonacci(n - 2);

}fibonacci(10) // 55

fibonacci(100) // 堆疊溢位

fibonacci(500) // 堆疊溢位

複製**

由上可見,遞迴非常消耗記憶體,因為需要同時儲存成千上百個呼叫幀,很容易發生「棧溢位」錯誤。但是也有解決的辦法,採用尾遞迴優化。

函式呼叫自身,稱為遞迴;如果尾呼叫自身,就稱為尾遞迴。 對於尾遞迴來說,由於只存在乙個呼叫棧,所以永遠不會發生「棧溢位」錯誤。

尾遞迴版 **實現

function fibonacci2 (n , ac1 = 1 , ac2 = 1) ;

return fibonacci2 (n - 1, ac2, ac1 + ac2);

}fibonacci2(100) // 354224848179262000000

fibonacci2(1000) // 4.346655768693743e+208

複製**

上面**雖然簡潔,但是不易想到

3.2.3 那接下來我們用佇列實現一遍 思路分析

當迴圈結束後,佇列裡面只有兩個元素,用dequeue方法移除頭部元素後,再用head方法獲取的頭部元素就是最終的結果,而且此方法不會產生「棧溢位」錯誤。

佇列版 **實現

queue.dequeue();

return queue.head();

}console.log("fibonacci", fibonacci(10)); // 55

console.log("fibonacci", fibonacci(100)); // 354224848179262000000

}複製**

3.3 列印楊輝三角

3.3.2 思路分析

3.3.3 **實現

複製**

4.佇列總結

使用佇列的例子還有很多,比如逐層列印一顆樹上的節點,還有訊息通訊使用的socket,當大量客戶端向服務端發起連線,而服務端擁擠時,就會形成佇列,先來的先處理,後來的後處理,當佇列滿時,新來的請求直接拋棄掉。 資料結構在系統設計中的應用非常廣泛,只是我們水平達不到那個級別,知道的太少,但如果能理解並掌握這些資料結構,那麼就有機會在工作中使用它們並解決一些具體的問題,當我們手裡除了錘子還有電鋸時,那麼我們的眼裡就不只是釘子,解決問題的思路也會更加開闊。

5.參考

阮一峰-函式的擴充套件

JavaScript資料結構之棧結構

棧也是一種非常常見的資料結構,並且在程式中的應用非常廣泛.我們先來簡單認識一下棧結構,它的特點和應用場景等.棧結構 棧 stack 它是一種運算受限的線性表,後進先出 lifo 生活中類似於棧的 棧結構的 程式中什麼是使用棧實現的呢?函式呼叫棧 棧面試題 我們來實現乙個類,用於模擬棧中的操作.棧的建...

資料結構 棧(JavaScript)

棧是一種遵從後進先出 lifo 原則的有序集合。新新增的或待刪除的元素都儲存在棧的 末尾,稱作棧頂,另一端就叫棧底。在棧裡,新元素都靠近棧頂,舊元素都接近棧底。舉個栗子,差不多這樣子。初始化棧的高度以及棧頂指標 var length 0 var top null 宣告常用方法 this.push f...

二 javascript資料結構

1 識別符號 var test test 定義變數開頭不能是數字 var 1a 1a 定義變數開頭可以是下劃線 var a a 定義變數開頭可以是中文 var 變數 a 2 關鍵字與保留字 就是這些保留字關鍵字,你不能定義變數或者函式等等,反正別用就行了 abstract arguments boo...