1. 程式人生 > >陣列、連結串列、堆疊和佇列、線性表和順序表

陣列、連結串列、堆疊和佇列、線性表和順序表

  • 線性表是具有n個(資料元素)的有限序列(n>0)
  • 資料:資訊的載體,能夠被計算機識別、儲存、加工,包括整數、實數、字串、影象、聲音等 資料元素:資料的基本單位,也稱結點、元素、頂點(圖)、記錄。一個數據元素可由若干個資料項組成,比如線性表中每個資料元素由姓名、性別、年齡三個資料項組成  資料項:是具有獨立寒意的最小標識單元,也稱欄位、域、屬性等 資料結構:指資料之間的相互關係,即組織形式,有邏輯結構(一般程式中出現的形式)和物理結構之分(記憶體中的連續儲存形式);邏輯結構又有線性(非空,僅由一個開始結點和一個終端結點,除首尾結點之外,所有節點均只有一個直接前區和一個直接後繼,如一維陣列、棧、佇列、連結串列、串等)和非線性之分(一個結點可以有多個直接前區和多個直接後繼,如多維陣列、廣義表、樹、圖等) 

資料結構:是指相互之間存在一種或多種特定關係的資料元素的集合。聽起來是不是很抽象,簡單理解:資料結構就是描述物件間邏輯關係的學科。比如:佇列就是一種先進先出的邏輯結構,棧是一種先進後出的邏輯結構,家譜是一種樹形的邏輯結構!(初學資料結構的時候很不理解為什麼有“棧”這個東西;佇列很容易理解---無論購物就餐都需要排隊;棧可以認為就是個棧道---只允許一個人通過的小道,而且只能從一端進入,然後再從這端返回,比如你推了個箱子進去啦,第二個人也推個箱子進去,此時只能等後進來的這個人拉著箱子出去後,你才能退出。)

資料儲存結構:它是計算機的一個概念,簡單講,就是描述資料在計算機中儲存方式的學科;常用的資料儲存方式就兩種:順序儲存,非順序儲存!順序儲存就是把資料儲存在一塊連續的儲存介質(比如硬碟或記憶體)上----舉個例子:從記憶體中拿出第100個位元組到1000個位元組間的連續位置,儲存資料;陣列就是典型的順序儲存!非順序儲存就是各個資料不一定存在一個連續的位置上,只要每個資料知道它前面的資料和後面的資料,就能把所有資料連續起來啦;連結串列就是典型的非順序儲存啦!


陣列、連結串列、堆疊和佇列是最基本的資料結構,任何程式都會涉及到其中的一種或多種。

順序儲存結構的應用:下標表示指標,儲存樹狀結構。圖的鄰接矩陣。可儲存線性或非線性結構。

陣列

陣列是最最基本的資料結構,很多語言都內建支援陣列。陣列是使用一塊連續的記憶體空間儲存資料,儲存的資料的個數在分配記憶體的時候就是確定的:

 

圖 1.1 包含 n 個數據的陣列

訪問陣列中第 個數據的時間花費是 O(1) 但是要在陣列中查詢一個指定的資料則是 O(N)。當向陣列中插入或者刪除資料的時候,最好的情況是在陣列的末尾進行操作,時間複雜度是O(1) ,但是最壞情況是插入或者刪除第一個資料,時間複雜度是 

O(N) 。在陣列的任意位置插入或者刪除資料的時候,後面的資料全部需要移動,移動的資料還是和資料個數有關所以總體的時間複雜度仍然是 O(N) 

 

圖 1.2 向陣列中插入資料

連結串列

連結串列是在非連續的記憶體單元中儲存資料,並且通過指標將各個記憶體單元連結在一起,最有一個節點的指標指向 NULL 。連結串列不需要提前分配固定大小儲存空間,當需要儲存資料的時候分配一塊記憶體並將這塊記憶體插入連結串列中。

在連結串列中查詢第 個數據以及查詢指定的資料的時間複雜度是 O(N) ,但是插入和刪除資料的時間複雜度是 O(1) ,因為只需要調整指標就可以:

 

圖 2.1 連結串列

 

圖 2.2 向連結串列中插入一個數據

 

圖 2.3 從連結串列中刪除一個數據

向上面這樣的連結串列結構在插入和刪除的時候程式設計會比較困難,因為需要記住當前節點的前一個節點,這樣才能完成插入和刪除。為了簡便通常使用帶有頭節點的連結串列:

 

圖 2.4 帶有頭節點的單鏈表

上面的連結串列是單鏈表,此外還有雙鏈表,就是節點中包含指向下一個節點的指標和指向上一個節點的指標:

 

2.5 雙向連結串列

不帶有頭節點的雙向連結串列在插入和刪除資料的時候也不會出現單鏈表那樣的問題。此外還有一種連結串列是迴圈連結串列,它是將雙向連結串列的頭尾相接:

 

圖 2.6 雙向迴圈連結串列

向迴圈雙向連結串列和迴圈連結串列中插入或者從中刪除資料只是多移動幾個指標。

設一個連結串列最常用的操作是在末尾插入結點和刪除尾結點,則選用(帶頭結點的雙迴圈連結串列)最節省時間。

  • 首先總在末位操作。所以使用迴圈連結串列。 又因為要執行刪除操作。若使用單迴圈連結串列,例如對....->X->Y>Z->...,Y刪除後無法一步訪問X。若雙迴圈連結串列,可向回訪問。 

堆疊

堆疊實現了一種後進先出的語義 (LIFO) 。可以使用陣列或者是連結串列來實現它:

 

圖 3.1 堆疊

對於堆疊中的資料的所有操作都是在棧的頂部完成的,只可以檢視棧頂部的資料,只能夠向棧的頂部壓入資料,也只能從棧的頂部彈出資料。

佇列

   (1)  佇列實現了先入先出的語義 (FIFO) 。佇列也可以使用陣列和連結串列來實現:

 

圖 4.1 佇列

佇列只允許在隊尾新增資料,在隊頭刪除資料。但是可以檢視隊頭和隊尾的資料。還有一種是雙端佇列,在兩端都可以插入和刪除:

 

圖 4.2 雙端佇列

(2)迴圈佇列的相關條件和公式

隊尾指標是rear ,隊頭指標是front,其中QueueSize為迴圈佇列的最大長度

2.1 隊空條件:rear==front

2.2 隊滿條件:(rear+1)%QueueSize==front

2.3 計算佇列長度: (rear-front+QueueSize)%QueueSize

2.4 入隊 :(rear+1)%QueueSize

2.5 出隊:(front+1)%QueueSize

(3)迴圈佇列的儲存結構

迴圈佇列是佇列的一種順序儲存結構嗎

是的····順序儲存就是指用一組連續的儲存單元依次儲存,鏈式儲存記憶體中地址不是挨著的,迴圈佇列增設了兩個指標頭指標和尾指標,實現空間的最大利用


5、線性表和順序表

線性表是邏輯概念,只要所有的資料在邏輯上是一維的都可以認為是線性表。線性表包括順序表(棧,佇列等),連結串列(棧,佇列等)。跟線性表相對的概念應該是樹或者堆。
 
順序表是空間概念,指的是所有的資料在儲存空間上順序排列,而跟具體的操作方式無關。與順序表相對的概念只有連結串列。