天天看點

Python資料結構與算法基礎|第一期:公共基礎知識——資料結構基本概念與簡單的線性結構

學習Python基礎文法的過程中,在分析一個問題并試圖寫出實際解決問題的代碼時,我常常發現寫出的代碼比較混亂,解決問題的過程并不是很清晰。是以,我希望通過學習一些資料結構與算法的知識來解決這個問題,并在這個過程中練習Python語言的使用、加深對Python語言的認識。

這個系列中我們将簡單介紹一些資料結構與算法的基礎概念,通過代碼實作來更好的加深了解,為其它複雜的資料結構與算法的學習打好基礎。

資料結構的基本概念與表示方式

  1. 資料結構:有互相關聯的資料元素的集合,包含“資料”與“結構”兩個要素。
  • 資料:需要處理的資料元素的集合,一般來說具有某個共同的特征。
  • 結構:集合中各個資料元素間存在的某種關系,具體包括邏輯結構與存儲結構。
    • 邏輯結構:通過兩兩元素之間的前後件關系(即直接前驅與直接後繼關系)來反映資料元素間的邏輯結構。
    • 存儲結構:又稱資料的實體結構,是資料的邏輯結構在計算機中的存放方式。
  1. 資料結構的表示:

    (1). 通過二進制組B = (D,R)表示。其中B表示資料結構,D是資料元素的集合,R是資料元素間的前後件關系構成的集合,其中資料元素間的前後件關系也用二進制組表示。

    (2).通過由方框與箭頭構成的圖表示。其中标有元素值的方框用來表示資料元素,一般稱之為資料節點。由前件指向後件的箭頭用來表示資料元素間的邏輯結構。

  2. 由前後件關系引出的節點的基本概念:

    (1).根節點:沒有前件的節點。

    (2).葉子節點:沒有後件的節點。

    (3).内部節點:除了根節點與葉子節點以外的全部節點。

  3. 線性結構與非線性結構: 線性結構指滿足有且隻有一個根節點、每一個節點最多隻有一個前件也最多隻有一個後件的非空資料結構。不滿足這些特點的資料結構稱為非線性結構。常見的非線性結構包括樹形結構與網狀結構。

簡單的線性結構:棧、隊列、線性連結清單以及循環連結清單

注:我們不讨論空的線性表。

a. 線性表:

線性結構常稱為線性表。可以用元組

Python資料結構與算法基礎|第一期:公共基礎知識——資料結構基本概念與簡單的線性結構

來表示,節點個數n稱為線性表的長度。

線性表具有以下結構特點:

  1. 隻有一個根節點。
  2. 有且隻有一個終端節點(葉子節點)。
  3. 除根節點與終端節點外,其他所有節點有且隻有一個前件,也有且隻有一個後件。
b. 順序表:采用順序存儲的線性表

線性表可以采用順序存儲與連結存儲兩種存儲結構。其中順序存儲的特點為

  1. 線性表中所有元素所占的存儲結構是連續的。
  2. 線性表中各資料元素在存儲空間中是按照邏輯順序依次存放的。

在順序表中,其前後件在存儲空間中是緊鄰的,且前件元素一定在後件元素之後。

c. 棧(Stack)

棧是一種特殊的線性表,其原則是“Last In First Out”,即棧的插入與删除都限定在表的同一端進行,允許插入與删除的一端稱為棧頂、不允許的一端稱為棧底。當棧中沒有元素時,稱此時的棧為空棧。我們可以用圖示

Python資料結構與算法基礎|第一期:公共基礎知識——資料結構基本概念與簡單的線性結構

來表示棧,其中有兩個指針分别指向棧頂元素與棧底元素,指向棧頂元素的指針反映棧的狀态變化,a1為棧底元素,an為棧頂元素,棧中所有元素按照a1、a2、… 、an的順序進入,相應的,退棧的第一個元素為棧頂元素an。

棧的基本運算包括

  1. 入棧
  2. 退棧
  3. 讀取棧頂元素
d. 隊列(Queue)

隊列是一種First In First Out 的線性表,即允許在表的一端(隊頭或排頭)進行删除、在表的另一端(隊尾)進行插入。我們可以用圖示

Python資料結構與算法基礎|第一期:公共基礎知識——資料結構基本概念與簡單的線性結構

來表示隊列,其中a1稱為隊頭元素,an稱為隊尾元素,隊列中的元素按照a1、a2、… 、an的順序進入隊列,也按照這個順序依次退出隊列。隊列的狀态由隊頭指針front和隊尾指針rear來反映。

e. 循環隊列

在實際中,隊列的順序存儲結構一般采用循環隊列形式,即将隊列存儲空間的最後一個位置繞到第一個位置,形成邏輯上的環狀空間。在循環隊列中,指針front = rear時無法判斷是空隊列還是滿隊列,所有常增加一個标志來區分空隊列與滿隊列。

關于循環隊列,在此系列第四、五期進行了介紹并使用Python進行了實作,具體可以閱讀後續内容。

f. 線性連結清單

與順序表不同,線性連結清單是線性表的鍊式存儲結構。由于此類連結清單每個節點隻有一個指針域,是以又稱單連結清單。線性連結清單的存儲單元是任意的,節點在存儲空間的位置關系與邏輯關系并不一緻。各節點的前後件關系通過節點的指針來表示,通過一個特殊指針指向清單中第一個節點,稱之為頭指針(HEAD),當其為NULL或0時,連結清單為空。由于沒有後件,是以線性連結清單最後一個節點的指針域為空(即值為NULL或0)。

g. 雙向連結清單

為了更友善的從某個節點出發找到其它節點,我們對線性連結清單的每個節點設定兩個指針,稱之為左指針與右指針,分别存放前件與後件的位址。這樣的連結清單稱為雙向連結清單,其示意圖為

Python資料結構與算法基礎|第一期:公共基礎知識——資料結構基本概念與簡單的線性結構
i. 循環連結清單

在單連結清單的第一個節點前增加一個表頭節點,HEAD指向表頭節點且最後一個節點的指針域由空改為指向表頭節點,這樣的連結清單中所有節點構成了環狀鍊,我們稱之為循環連結清單。

表頭節點是循環連結清單中固定的,是以即使表中沒有資料元素,也至少存在一個表頭節點。在循環連結清單中,隻要指出任何一個節點的位置,就可以從它出發通路表中所有的節點。