線性表的鏈式表示 鍊錶詳解

2021-10-22 17:16:10 字數 3138 閱讀 1345

(二)迴圈鍊錶

(三)雙向鍊錶

(四)總結

(五)參考文獻

線性表的鏈式儲存結構即鍊錶,其特點是用一組任意的儲存單元儲存線性表的資料元素,這組在記憶體中的儲存單元可以是連續的,也可以是不連續的。鍊錶,顧名思義,是由各個節點鏈結。節點的資訊包含資料域指標域。資料域儲存元素資訊,指標域用來儲存直接後繼節點的位址(兩節點間的箭頭)。n個節點鏈結成乙個鍊錶,每個元素節點都只有乙個指標域,又稱為單鏈表

我們以(a,b,c,d)四個英文本母作為資料域的四個節點,每個節點的資料域儲存該元素(字母),其指標域還要儲存下乙個字母的位址,同時每個節點在記憶體中也有專屬的位址,即儲存位址。

鍊錶的儲存必須從頭指標開始。頭指標也是乙個元素節點,只是它並不儲存資料元素,只儲存第乙個元素節點的位址。同時最後乙個元素d沒有直接後繼元素,故指標域為空,我們賦值為null。示意圖如下圖所示:

頭指標20

儲存位址

資料域指標域29b

464dnull20a

2946c4

1.首先從頭指標開始找到第乙個元素的位址20,我們找到該位址並遍歷了a字母,同時該a字母節點又記錄著b節點的位址29,所以我們找到位址29遍歷,獲取到b字母…如此進行下去,找到d字母時候,由於它的指標域是null,故鍊錶遍歷終止。如此,我們可以逐步獲取到abcd四個字母。

2.這個過程我們可以模擬於尋找寶藏的遊戲。一張藏寶圖只能記錄乙個寶貝的位置,假如你是乙個有著第一張藏寶圖(頭指標/頭節點)的商人(暗暗自喜),所以你按照藏寶圖的指引來到了藏有第乙個寶貝a(資料域)的20號洞穴(指標域)並將它取出來。此時,你驚奇地發現這個寶貝上還記錄著下乙個寶貝(b)的藏寶地(29),於是事不宜遲,你馬上趕到了29號洞穴…當找到d寶貝之後,上邊並沒有下乙個寶貝的位址。於是,我們一共獲得了abcd四件寶貝(還不錯哈)。

將四個元素節點轉換成線性圖示:

**:1.l為頭節點(頭指標),指標域記錄a元素的位址,資料域不記錄元素。相當於l有一條到a的箭頭

2. abcd事實上在記憶體中不連續,所以只需要記錄下乙個節點的位址,可以最大限度節省記憶體空間。

上邊說了一些鍊錶的基礎內容,那麼真正程式實現是什麼樣的呢。我們下面我們以c++語言為例,實現鍊錶的關鍵程式**。

乙個鍊錶節點需要指標域於資料域,所以首先定義乙個結構體。

typedef

int elemtype

typedef

struct lnode

lnode,

*llist;

lnode結構體型別,同時對於lnode的指標我們定義為llist,避免後期宣告指標時需要llist *a,*b。較為繁瑣。

void

listcreate

(llist& l, elemtype n, elemtype a)

}

對鍊錶的元素的插入操作分為頭插法和尾插法。頭插法是在頭節點之後,第乙個節點之前進行插入,這種方法會將元素序列逆序。尾插法是在鍊錶最後乙個節點之後插入,可以保持原序列的原有順序不變。

將該新建節點的後繼賦值為第乙個節點的位址,而第乙個節點的位址是由頭節點記錄的,所以應該用p->next=l->next;

將該節點位址賦值給頭節點,即頭插法中將新來的節點作為第乙個節點。

該程式實現對與鍊錶的遍歷,同時對每乙個遍歷到的元素進行最簡單的輸出至控制台。讀者可以嘗試手動畫表執行程式,會讓理解更加深刻。

void

print

(llist l)

cout << endl;

}

已經對鍊錶有些掌握的我們,可以試著做一做應用題。

problem:刪除鍊錶的重複元素,假設有線性表(4,3,3,1,1,1),經過演算法遍歷後成為線性表(4,3,1)。

analysis: 刪除重複的元素,可以遍歷原有鍊錶,宣告兩個指標p,q,p指向前乙個遍歷的節點(可能會準備刪除),q指向當前節點。如果該資料域元素和其直接前驅的元素相同我們將p指向q的後繼(因為q會被刪除),同時刪除q節點。

時間複雜度可以控制在o(n),且不需要額外申請記憶體空間

**實現為:

bool

listdelete

(llist& l)

else

p = p-

>next;}}

return

true

;}

迴圈鍊錶是另一種形式的鏈式儲存結構,其特點為鍊錶最後乙個節點的指標域不再是null,而是指向頭節點l。整個鍊錶形成乙個閉合的環。故從表中任一節點出發都可以找到其他的節點。

其基礎操作域單向鍊錶基本一致,差別在於演算法中迴圈條件不是p是否為null,而是p是否和頭指標相同。

我們前面所討論的鍊錶,其節點都只有乙個指向直接後繼的指標域,故從某個節點出發只能使指標逐步後移去遍歷其他節點。如果想要找到某節點的前驅,則需要從頭節點出發。

顧名思義,在定義節點型別時,我們還需要增加乙個結構體成員,即指向直接前驅的指標。故乙個節點擁有兩個指標域。克服了單向鍊錶單向性的缺點。

與單向鍊錶類似,只不過多乙個前驅指標罷了。

typedef

int elemtype

typedef

struct dulnode

dulnode,

*dulist;

線性表包含順序表(陣列)和鍊錶,是最常用最簡單 的一種資料結構。其中順序表為線性表的順序儲存結構,即動態陣列。

鍊錶分為單向鍊錶、雙向鍊錶、迴圈鍊錶等多種結構。其優點在於不浪費任何記憶體空間、插入節點較為方便,不需要像順序表一樣移動元素、但是獲取對應節點不能像順序表一樣依靠索引,而是需要利用頭指標逐步後移來獲取。

順序表以元素在計算機內」物理位置「相鄰來表示線性表中資料元素之間的邏輯關係。而鍊錶不要求邏輯上相鄰的元素在物理位置上也相鄰,故失去了順序表隨機選取的優點。

嚴蔚敏,吳偉民. 資料結構(c語言版). 北京:清華大學出版社,1997.

線性表續篇 線性表的鏈式表示

public class 04linearlist02 初始化指標域和資料域 private node t obj,node n 得到當前節點的資料域 public t getdata 得到當前節點的指標域 public node getnext 鍊錶的長度 private int length 鍊...

線性表的鏈式表示

上篇文章是線性表的順序表示,本篇便是線性表的鏈式表示。主函式的步驟包括,輸入線性表資料,對鍊錶的刪除,插入。利用指標進行對鍊錶的訪問。同時為了增加程式可讀性,將結構體定義為lnode,linklist。include 線性表的鏈式表示 using namespace std typedef stru...

資料結構 線性表的鏈式表示(鍊錶)

下面介紹第二種順序表,也就是鍊錶 鍊錶有兩個,單鏈表和雙鏈表,先介紹單鏈表 include includetypedef struct nodenode,linklist node creatlist1 node head return head void output node head int ...