數據結構前言
數據結構是為實現對計算機數據有效使用的各種數據組織形式,服務於各類計算機操作。不同的數據結構具有各自對應的適用場景,旨在降低各種算法計算的時間與空間復雜度,達到最佳的任務執行效率。
如下圖所示,常見的數據結構可分為「線性數據結構」與「非線性數據結構」,具體為:「數組」、「鏈表」、「棧」、「隊列」、「樹」、「圖」、「散列表」、「堆」。
數組
數組是將相同類型的元素存儲於連續內存空間的數據結構,其長度不可變。
「可變數組」是經常使用的數據結構,其基於數組和擴容機制實現,相比普通數組更加靈活。常用操作有:訪問元素、添加元素、刪除元素。
鏈表
鏈表以節點為單位,每個元素都是一個獨立對象,在內存空間的存儲是非連續的。鏈表的節點對象具有兩個成員變量:「值 val
」,「后繼節點引用 next
」 。
棧
棧是一種具有 「先入后出」 特點的抽象數據結構,可使用數組或鏈表實現。
隊列
隊列是一種具有 「先入先出」 特點的抽象數據結構,可使用鏈表實現。
樹
樹是一種非線性數據結構,根據子節點數量可分為 「二叉樹」 和 「多叉樹」,最頂層的節點稱為「根節點 root」。以二叉樹為例,每個節點包含三個成員變量:「值 val」、「左子節點 left」、「右子節點 right」 。
圖
圖是一種非線性數據結構,由「節點(頂點)vertex」和「邊 edge」組成,每條邊連接一對頂點。根據邊的方向有無,圖可分為「有向圖」和「無向圖」。本文 以無向圖為例 開展介紹。
表示圖的方法通常有兩種:
鄰接矩陣: 使用數組 vertices存儲頂點,鄰接矩陣 edges 存儲邊; edges[i][j] 代表節點 i + 1 和 節點 j + 1 之間是否有邊。
鄰接表: 使用數組 vertices 存儲頂點,鄰接表 edges 存儲邊。edges 為一個二維容器,第一維i 代表頂點索引,第二維edges[i] 存儲此頂點對應的邊集和;例如 edges[0]=[1,2,3,4] 代表 vertices[0] 的邊集合為 [1, 2, 3, 4]。
鄰接矩陣 VS 鄰接表 :
鄰接矩陣的大小只與節點數量有關,即 N^2,其中 N為節點數量。因此,當邊數量明顯少於節點數量時,使用鄰接矩陣存儲圖會造成較大的內存浪費。
因此,鄰接表 適合存儲稀疏圖(頂點較多、邊較少); 鄰接矩陣 適合存儲稠密圖(頂點較少、邊較多)。
散列表
散列表是一種非線性數據結構,通過利用 Hash 函數將指定的「鍵 key
」映射至對應的「值 value
」,以實現高效的元素查找。
以上設計只適用於此示例,實際的 Hash 函數需保證低碰撞率、 高魯棒性等,以適用於各類數據和場景。
堆:
堆是一種基於「完全二叉樹」的數據結構,可使用數組實現。以堆為原理的排序算法稱為「堆排序」,
基於堆實現的數據結構為「優先隊列」。堆分為「大頂堆」和「小頂堆」,大(小)頂堆:任意節點的
值不大於(小於)其父節點的值
完全二叉樹定義: 設二叉樹深度為 k ,若二叉樹除第 kk 層外的其它各層(第 1 至 k-1層)的節點
達到最大個數,且處於第 k 層的節點都連續集中在最左邊,則稱此二叉樹為完全二叉樹。