【資料結構篇】認識資料結構

B發表於2021-04-27

這兩天正在跟了老師進行學習一個 Java 開源專案,基於各大資料結構的。

在翻了一圈部落格之後發現以前沒有系統的總結一下資料結構。

現補上此文。

一、資料結構的定義

資料結構是帶有結構特性的資料元素的集合,它研究的是資料的[邏輯結構]和資料的物理結構以及它們之間的相互關係,並對這種結構定義相適應的運算,設計出相應的演算法,並確保經過這些運算以後所得到的新結構仍保持原來的結構型別。

簡而言之,資料結構是相互之間存在一種或多種特定關係的資料元素的集合,即帶“結構”的資料元素的集合。“結構”就是指資料元素之間存在的關係,分為邏輯結構和儲存結構。

資料的邏輯結構和物理結構是資料結構的兩個密切相關的方面,同一邏輯結構可以對應不同的儲存結構。演算法的設計取決於資料的邏輯結構,而演算法的實現依賴於指定的[儲存結構]。

資料結構概念包含三方面:資料的邏輯結構、資料的儲存結構、對資料的操作

二、資料的邏輯結構

1、資料的邏輯結構是指資料元素之間的邏輯關係,用一個資料元素的集合和定義在此集合上的若干關係表示。

2、資料結構分為三種:線性結構、樹結構、圖,其中樹和圖是非線性結構。

(1)線性結構:是具有線性關係的資料結構,線性表的元素是有序數列,每個元素(除了頭和尾)有且僅有一個前驅和後繼。

(2)樹結構:資料元素之間具有層次關係的一種非線性結構,樹種資料元素通常稱為結點。樹結構的層次關係是指---->根結點沒有前驅結點,除了根以外的其他結點有且僅有一個父母結點,所有結點可有多個或零個後繼結點,或稱孩子結點。

(3)圖:每個資料元素可有多個前驅元素和多個後繼元素。

3、資料元素及其關係在計算機中的儲存表示或實現稱為“資料的儲存結構”,也稱物理結構。

三、資料結構的作用和意義

  1. 在許多型別的程式的設計中,資料結構的選擇是一個基本的設計考慮因素。許多大型系統的構造經驗表明,系統實現的困難程度和系統構造的質量都嚴重的依賴於是否選擇了最優的資料結構。

    許多時候,確定了資料結構後,演算法就容易得到了。有些時候事情也會反過來,我們根據特定演算法來選擇資料結構與之適應。不論哪種情況,選擇合適的資料結構都是非常重要的。

  2. 選擇了資料結構,演算法也隨之確定,是資料而不是演算法是系統構造的關鍵因素。這種洞見導致了許多種軟體設計方法和程式設計語言的出現,物件導向的程式設計語言就是其中之一。

  3. 資料結構是計算機儲存、組織資料的方式。資料結構是指相互之間存在一種或多種特定關係的資料元素的集合。通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率。資料結構往往同高效的檢索演算法和索引技術有關。

四、基本的資料結構都有什麼?

常用的資料結構有:陣列,棧,連結串列,佇列,樹,圖,堆,雜湊表等,如圖所示:

每一種資料結構都有著獨特的資料儲存方式,下面為大家介紹它們的結構和優缺點。

1、陣列

陣列是可以再記憶體中連續儲存多個元素的結構,在記憶體中的分配也是連續的,陣列中的元素通過陣列下標進行訪問,陣列下標從0開始。例如下面這段程式碼就是將陣列的第一個元素賦值為 1。

int[] data = new int[100];data[0] = 1;

**①優點:

**

  • 按照索引查詢元素速度快
  • 按照索引遍歷陣列方便

②缺點:

  • 陣列的大小固定後就無法擴容了
  • 陣列只能儲存一種型別的資料
  • 新增,刪除的操作慢,因為要移動其他的元素。

③適用場景:

  • 頻繁查詢,對儲存空間要求不大,很少增加和刪除的情況。

2、棧

棧是一種特殊的線性表,僅能線上性表的一端操作,棧頂允許操作,棧底不允許操作。 棧的特點是:先進後出,或者說是後進先出,從棧頂放入元素的操作叫入棧,取出元素叫出棧。

棧的結構就像一個集裝箱,越先放進去的東西越晚才能拿出來,所以,棧常應用於實現遞迴功能方面的場景,例如斐波那契數列。

3、佇列

佇列與棧一樣,也是一種線性表,不同的是,佇列可以在一端新增元素,在另一端取出元素,也就是:先進先出。從一端放入元素的操作稱為入隊,取出元素為出隊,示例圖如下:

圖片來自網路,侵權刪

使用場景:因為佇列先進先出的特點,在多執行緒阻塞佇列管理中非常適用。

4、連結串列

連結串列是物理儲存單元上非連續的、非順序的儲存結構,資料元素的邏輯順序是通過連結串列的指標地址實現,每個元素包含兩個結點,一個是儲存元素的資料域 (記憶體空間),另一個是指向下一個結點地址的指標域。根據指標的指向,連結串列能形成不同的結構,例如單連結串列,雙向連結串列,迴圈連結串列等。

①優點:

  • 連結串列是很常用的一種資料結構,不需要初始化容量,可以任意加減元素;
  • 新增或者刪除元素時只需要改變前後兩個元素結點的指標域指向地址即可,所以新增,刪除很快;

②缺點:

  • 因為含有大量的指標域,佔用空間較大;查詢元素需要遍歷連結串列來查詢,非常耗時。

③適用場景:

  • 資料量較小,需要頻繁增加,刪除操作的場景

5、樹

樹是一種資料結構,它是由n(n>=1)個有限節點組成一個具有層次關係的集合。把它叫做 “樹” 是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:

  • 每個節點有零個或多個子節點;
  • 沒有父節點的節點稱為根節點;
  • 每一個非根節點有且只有一個父節點;
  • 除了根節點外,每個子節點可以分為多個不相交的子樹;

在日常的應用中,我們討論和用的更多的是樹的其中一種結構,就是二叉樹。

二叉樹是樹的特殊一種,具有如下特點:

  • 每個結點最多有兩顆子樹,結點的度最大為2。
  • 左子樹和右子樹是有順序的,次序不能顛倒。
  • 即使某結點只有一個子樹,也要區分左右子樹。

二叉樹是一種比較有用的折中方案,它新增和刪除元素都很快,並且在查詢方面也有很多的演算法優化,所以,二叉樹既有連結串列的好處,也有陣列的好處,是兩者的優化方案,在處理大批量的動態資料方面非常有用。

? 擴充套件:

二叉樹有很多擴充套件的資料結構,包括平衡二叉樹、紅黑樹、B+樹等,這些資料結構二叉樹的基礎上衍生了很多的功能,在實際應用中廣泛用到。

例如mysql的資料庫索引結構用的就是B+樹,還有HashMap的底層原始碼中用到了紅黑樹。這些二叉樹的功能強大,但演算法上比較複雜,想學習的話還是需要花時間去深入的。

6、雜湊表

雜湊表,也叫雜湊表,是根據關鍵碼和值 (key和value) 直接進行訪問的資料結構,通過key和value來對映到集合中的一個位置,這樣就可以很快找到集合中的對應元素。

“記錄的儲存位置=f(key)”

這裡的對應關係 “f”稱為雜湊函式,又稱為雜湊 (hash函式),而雜湊表就是把Key通過一個固定的演算法函式既所謂的雜湊函式轉換成一個整型數字,然後就將該數字對陣列長度進行取餘,取餘結果就當作陣列的下標,將value儲存在以該數字為下標的陣列空間裡,這種儲存空間可以充分利用陣列的查詢優勢來查詢元素,所以查詢的速度很快。

雜湊表在應用中也是比較常見的,就如Java中有些集合類就是借鑑了雜湊原理構造的,例如HashMap,HashTable等,利用hash表的優勢,對於集合的查詢元素時非常方便的。

然而,因為雜湊表是基於陣列衍生的資料結構,在新增刪除元素方面是比較慢的,所以很多時候需要用到一種陣列連結串列來做,也就是拉鍊法。拉鍊法是陣列結合連結串列的一種結構,在Java較早前的hashMap底層的儲存就是採用這種結構,直到jdk1.8之後才換成了陣列加紅黑樹的結構,其示例圖如下:

img

從圖中可以看出,左邊很明顯是個陣列,陣列的每個成員包括一個指標,指向一個連結串列的頭,當然這個連結串列可能為空,也可能元素很多。我們根據元素的一些特徵把元素分配到不同的連結串列中去,也是根據這些特徵,找到正確的連結串列,再從連結串列中找出這個元素。

雜湊表的應用場景很多,當然也有很多問題要考慮,比如雜湊衝突的問題,如果處理的不好會浪費大量的時間,導致應用崩潰。

7、堆

堆是一種比較特殊的資料結構,可以被看做一棵樹的陣列物件,具有以下的性質:

  • 堆中某個節點的值總是不大於或不小於其父節點的值;
  • 堆總是一棵完全二叉樹。

將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。常見的堆有二叉堆、斐波那契堆等。

堆的定義如下:n個元素的序列{ \(k_1,k_2,k_i,…,k_n\)}當且僅當滿足下關係時,稱之為堆。

(\(k_i <= k_{2·i},k_i <= k_{2·i+1}\))或者(\(k_i >= k_{2·i},k_i >= k_{2·i+1}\)), (\(i = 1,2,3,4…n/2\)),滿足前者的表示式的成為小頂堆,滿足後者表示式的為大頂堆,這兩者的結構圖可以用完全二叉樹排列出來,示例圖如下:

因為堆有序的特點,一般用來做陣列中的排序,稱為堆排序。

8、圖

圖是由結點的有窮集合V和邊的集合E組成。其中,為了與樹形結構加以區別,在圖結構中常常將結點稱為頂點,邊是頂點的有序偶對,若兩個頂點之間存在一條邊,就表示這兩個頂點具有相鄰關係。

按照頂點指向的方向可分為無向圖和有向圖:

圖是一種比較複雜的資料結構,在儲存資料上有著比較複雜和高效的演算法,分別有鄰接矩陣 、鄰接表、十字連結串列、鄰接多重表、邊集陣列等儲存結構,這裡不做展開,同學們有興趣可以自己學習深入。

那作為初識資料結構的小白們,該如何才能學好資料結構呢?其實對於資料結構的學習,只要對掌握方法就變得遊刃有餘啦!接下來給大家劃重點啦!請注意理解資料結構的一個經典等式:

資料結構 = 結構定義 + 結構操作

相關文章