JavaScript資料結構與演算法
1.1.什麼是資料結構?
資料結構就是在計算機中,儲存和組織資料的方式。常見的資料結構:
-
陣列(Aarray)
-
棧(Stack)
-
連結串列(Linked List)
-
圖(Graph)
-
散列表
-
佇列(Queue)
-
樹(Tree)
-
堆(Heap)
1.2.什麼是演算法?
演算法(Algorithm)的定義
-
一個有限指令集,每條指令的描述不依賴於語言;
-
接收一些輸入(有些情況下不需要輸入);
-
產生輸出;
-
一定在有限步驟之後終止;
演算法通俗理解:解決問題的辦法/步驟邏輯。資料結構的實現,離不開演算法。
二、棧結構(Stack)
2.1.簡介
陣列是一個線性結構,並且可以在陣列的任意位置插入和刪除元素。而棧和佇列就是比較常見的受限的線性結構。
棧的特點為先進後出,後進先出(LIFO:last in first out)。
程式中的棧結構:
-
函式呼叫棧:A(B(C(D()))):即A函式中呼叫B,B呼叫C,C呼叫D;在A執行的過程中會將A壓入棧,隨後B執行時B也被壓入棧,函式C和D執行時也會被壓入棧。所以當前棧的順序為:A->B->C->D(棧頂);函式D執行完之後,會彈出棧被釋放,彈出棧的順序為D->C->B->A(函式呼叫棧);
-
遞迴:為什麼沒有停止條件的遞迴會造成棧溢位?比如函式A為遞迴函式,不斷地呼叫自己(因為函式還沒有執行完,不會把(自己)函式彈出棧),不停地把相同的函式A壓入棧,最後造成棧溢位
棧結構的實現
-
基於陣列實現
-
基於連結串列實現
什麼是連結串列?
一種資料結構,javascript中並沒有自帶連結串列
-
先實現棧結構基於陣列
對陣列進行一層包裝,使其具有棧的特性
棧的操作
-
push(element)//將元素壓入棧
-
pop //從棧中取出元素,並返回值
-
peek//返回棧頂元素
-
isEmpty//判斷棧是否為空,為空返回true不為空false
-
size//返回棧的長度
-
toString//toString方法
應用----十進位制轉成二進位制
只需要將給十進位制數字和2整除。直到結果是0為止
將10轉換成二進位制
先將0壓入棧,以此類推,最後入棧的數為1,後依次出棧
思路:將數除2獲取餘數依次存入棧內,整除2後的結果,作為下一次執行的結果繼續迴圈,直到結果0為止;出棧
-
while迴圈
-
Math.floor()
三、認識佇列
是一種受限的線性結構,只允許在前端刪除元素,在後端插入元素,符合先進先出(FIFO first in first out)
佇列應用
列印佇列
列印文件,按輸入順序
執行緒佇列
在開發中,為了讓任務並行處理,通常開啟多個執行緒,但不能讓大量執行緒同時執行處理任務(佔用過多資源),因此使用執行緒佇列。其會依照次序來啟動執行緒,並且處理對應的任務。
封裝佇列常見操作
-
後端新增 enter-queue------enqueue
-
前端刪除 delete-queue-----dequeue
-
返回前端元素,對佇列不做修改front
-
判斷為空isEmpty
-
長度size
-
toString
擊鼓傳花
-
擊鼓傳花是一個常見的面試演算法題.使用佇列可以非常方便的實現最終的結果.
-
原遊戲規則:
-
班級中玩一個遊戲,所有學生圍成一圈,從某位同學手裡開始向旁邊的同學傳一束花.
-
這個時候某個人(比如班長),在擊鼓,鼓聲停下的一顆,花落在誰手裡,誰就出來表演節目.
-
-
修改遊戲規則.
-
幾個朋友一起玩一個遊戲,圍成一圈,開始數數,數到某個數字的人自動淘汰.
-
最後剩下的這個人會獲得勝利,請問最後剩下的是原來在哪一個位置上的人?
-
引數:所有參與人的姓名,基於的數字
-
結果:最終剩下的一人的姓名
-
思路:假設5為爆炸數字,將5個人依次放入佇列中,第一個人數到1後繼續新增到佇列的後端,第二個人數到2後繼續新增到佇列的後端,以此類推,到第五個人數5後淘汰,此時剩餘4個人,迴圈到第四個人數4,後面跟著的1號人數5,1號淘汰,3號淘汰,4號淘汰,後2號勝利
步驟:
-
建立一個佇列結構
-
將所有人依次加入到佇列中
-
迴圈將沒有喊到num的人依次新增到佇列後端,喊到num的人淘汰
-
當佇列剩餘1個人時輸出其name和下標
優先順序佇列
-
在插入一個元素的時候會考慮該資料的優先順序,和其他資料優先順序進行比較,比較完成後,可以得出這個元素在佇列中正確的位置
-
每個元素不再只是一個數據,而是包含資料的優先順序,在新增方式中,根據優先順序放入正確的位置
應用
-
登機順序,頭等艙與商務艙的登機順序,頭等艙的優先順序高於商務艙的優先順序。
-
急診科
-
計算機中,每個執行緒的任務重要性不同
四、連結串列
-
連結串列中的元素在記憶體中不必是連續的空間,實現靈活的記憶體動態管理
-
連結串列的每個元素由一個儲存元素本身的節點和指向下一個元素的引用組成
-
連結串列不必在建立時就確定大小,並且大小可以無限的延伸下去
-
連結串列在插入和刪除資料時,時間複雜度可以達到O(1),比陣列效率高很多
缺點:
-
連結串列在訪問任何一個元素時,都需要從頭開始
-