接上篇-資料結構之棧
資料結構之---佇列
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...