JS 數據結構

一、認識數據結構

什麼是數據結構?下面是維基百科的解釋

數據結構是計算機存儲、組織數據的方式

數據結構意味着接口或封裝:一個數據結構可被視爲兩個函數之間的接口,或者是由數據類型聯合組成的存儲內容的訪問方法封裝

我們每天的編碼中都會用到數據結構,因爲數組是最簡單的內存數據結構,下面是常見的數據結構:

  • 數組(Array)
  • 棧(Stack)
  • 堆(Heap)
  • 隊列(Queue)
  • 鏈表(Linked List)
  • 樹(Tree)
  • 圖(Graph)
  • 散列表(Hash)

其中,隊列是一種類似數組的數據結構,它們之間的區別僅僅體現在數據項的插入和移除的方式上。鏈表則是另一種節點與節點之間維持引用關係的數據結構。散列表(也稱哈希表)依賴散列函數來保存和定位數據。

就複雜性而言,棧和隊列是最簡單的兩種,並且二者都可以通過鏈表來進行構造。樹和圖則是最複雜的,因爲它們繼承了鏈表的概念。散列表需要利用這些數據結構來可靠地執行。就執行效率而言,鏈表在對數據的記錄和排序上表現最好,同時散列表也更加擅長查找和提取數據。

二、棧、堆、隊列

詳見

三、鏈表(Linked List)

如同數組一樣,鏈表也是按照順序存儲數據元素,但卻不是通過維護索引實現,鏈表是通過指向其他節點的指針實現。第一個節點稱之爲頭節點,最後一個節點被稱爲尾節點。在單向鏈表中,每個節點都只有一個指針,該指針指向下一個節點。我們從頭結點開始向後遍歷鏈表中剩餘的節點。在雙向鏈表中,還有一個指向前一個節點的指針,因此可以實現從尾部向頭部「反向」遍歷鏈表。

由於只需要改變節點的指針,所以鏈表插入和刪除某個節點操作所消耗的時間是固定的。在數組中執行同樣的操作需要消耗的時間卻是線性增長的,因爲緊隨其後的節點都需要被移動。另外,只要還有空間,鏈表就可以增長。因此,即使是自動調整大小的「動態」數組,操作代價也可能變得出乎意料的高。爲了查找或者編輯鏈表中的某個元素,可能會遍歷整個鏈表,遍歷的時間複雜度是線性的。但如果使用數組索引,卻只需要花費一丁點的時間。

四、樹(Tree)

樹(Tree)類似於鏈表,但不同的是樹在不同的層級下引用多個子節點。換句話說,每個節點最多隻能有一個父節點。文檔對象模型(DOM)就是這樣的結構,有一個根節點 html, html 中的分支都包含在 head 和 body 節點中,然後進一步細分爲所有我們熟悉的 HTML 標籤。在 JS 內部,原型繼承和與 React 組件的組合也會產生樹結構。當然,React 中作爲代表內存中 DOM 結構的虛擬 DOM,同樣也是一個樹結構。

二叉樹是一種比較特殊的樹,因爲二叉樹中的每個節點最多隻能有兩個子節點。左子節點的值必須小於或等於其父節點的值,同時右子節點的值必須大於其父節點的值。以這種方式組織和平衡樹結構,由於每次迭代中我們可以忽略二分之一的分支,所以就可以在對數時間內查找任意值。插入和刪除操作同樣也在對數時間內完成。除此之外,可以輕鬆地最左葉節點中和最右葉節點中,分別找到最小值和最大值。

對樹的遍歷可以以垂直或水平過程進行。深度優先遍歷(DFT)是在垂直方向上,其遞歸算法相較於迭代算法來說更加優雅。可以通過前序、中序、後序來遍歷節點。如果需要先訪問根節點,然後再檢查子節點,應該選擇前序遍歷。如果需要先訪問子節點,然後再檢查根節點,則應選擇後序遍歷。顧名思義,中序遍歷就是按照左、根、右的順序遍歷節點。這些性質使得二叉查找樹非常適合排序。

廣度優先遍歷(BFT)是在水平方向上,其迭代算法相較於遞歸算法來說更加優雅。廣度優先遍歷需要使用隊列來跟最每次迭代的所有子節點。但是,此類隊列所需的內存可能並不小。如果樹的形狀更寬,則廣度優先遍歷是更好的選擇。同樣,廣度優先遍歷在任何兩個節點之間採用的路徑是最短的路徑。

五、圖(Graph)

如果一棵樹可以擁有多個父節點,那麼它就變成了一張圖(Graph)。在圖中連接每個節點的邊,可以是有方向的,也可以是無方向的,可以是有權重的,也可以是無權重的。既有方向也有權重的邊類似於向量。

社交網絡和互聯網本身也是圖。自然界中最複雜的圖是我們人類的大腦。現在,我們試圖將神經網絡複製到機器中,期望使機器具有「超級智能」。

六、散列表(Hash Table)

列表是一種包含鍵值(Key-Value)對的,類似字典的數據結構。在內存中的每對鍵值都通過散列函數(Hash Function)來確定其位置,散列函數接受鍵(Key)作爲參數,並返回該鍵值對應當插入或讀取的地址。如果兩個或者多個鍵返回的地址是相同的,則會發生衝突(Collision)。爲了健壯起見,getter 和 setter 應該預見到這些事件,以確保可以恢復所有的數據,並且不會覆蓋任何數據。通常,可以使用鏈表來實現最簡單的解決方案,或者搞一個超大的表也是可行的。

 

參考:https://juejin.im/post/5de754faf265da33b12e8615

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章