資料結構 鍊錶

2021-06-29 04:18:00 字數 4935 閱讀 1357

鍊錶中的資料是以節點來表示的,每個結點的構成:元素(資料元素的映象) + 指標(指示後繼元素儲存位置),元素就是儲存資料的儲存單元,指標就是連線每個結點的位址資料。

鍊錶的結點結構

┌──┬──┐

│data│next│

└──┴──┘

data域–存放結點值的資料域

next域–存放結點的直接後繼的位址(位置)的指標域(鏈域)

以「結點的序列」表示線性表稱作線性鍊錶(單鏈表)

typedef

char datatype; //假設結點的資料域型別為字元

typedef

struct nodelistnode;

typedef listnode *linklist;

listnode *p;

linklist head;

注意:①linklist和listnode *是不同名字的同乙個指標型別(命名的不同是為了概念上更明確)

②linklist型別的指標變數head表示它是單鏈表的頭指標

③listnode *型別的指標變數p表示它是指向某一結點的指標

①生成結點變數的標準函式

p=( listnode *)malloc(sizeof(listnode));

//函式malloc分配乙個型別為listnode的結點變數的空間,並將其首位址放入指標變數p中

②釋放結點變數空間的標準函式

free(p);//釋放p所指的結點變數空間

③結點分量的訪問

利用結點變數的名字*p訪問結點分量

方法一:(*p).data和(*p).next

方法二:p-﹥data和p-﹥next

④指標變數p和結點變數*p的關係

指標變數p的值——結點位址

結點變數*p的值——結點內容

(*p).data的值——p指標所指結點的data域的值

(*p).next的值——*p後繼結點的位址

*((*p).next)——*p後繼結點

單鏈表的運算

1、建立單鏈表

假設線性表中結點的資料型別是字元,我們逐個輸入這些字元型的結點,並以換行符』\n』為輸入條件結束標誌符。動態地建立單鏈表的常用方法有如下兩種:

(1) 頭插法建表

① 演算法思路

從乙個空表開始,重複讀入資料,生成新結點,將讀入資料存放在新結點的資料域中,然後將新結點插入到當前鍊錶的表頭上,直到讀入結束標誌為止。

② 具體演算法實現

linklist creatlistf(void)

return head;

}

(2) 尾插法建表

① 演算法思路

從乙個空表開始,重複讀入資料,生成新結點,將讀入資料存放在新結點的資料域中,然後將新結點插入到當前鍊錶的表尾上,直到讀入結束標誌為止。

② 具體演算法實現

linklist creatlistr(void)

//endwhile

if (r!=

null)

r->next=

null;//對於非空表,將尾結點指標域置空head=s;

return head;

}

注意:

⒈開始結點插入的特殊處理

由於開始結點的位置是存放在頭指標(指標變數)中,而其餘結點的位置是在其前趨結點的指標域中,插入開始結點時要將頭指標指向開始結點。

⒉空表和非空表的不同處理

若讀入的第乙個字元就是結束標誌符,則鍊錶head是空表,尾指標r亦為空,結點*r不存在;否則鍊錶head非空,最後乙個尾結點*r是終端結點,應將其指標域置空。

(3) 尾插法建帶頭結點的單鏈表

①頭結點及作用

頭結點是在鍊錶的開始結點之前附加乙個結點。它具有兩個優點:

⒈由於開始結點的位置被存放在頭結點的指標域中,所以在鍊錶的第乙個位置上的操作就和在表的其它位置上操作一致,無須進行特殊處理;

⒉無論鍊錶是否為空,其頭指標都是指向頭結點的非空指標(空表中頭結點的指標域空),因此空表和非空表的處理也就統一了。

②尾插法建帶頭結點鍊錶演算法

linklist creatlistr1(void)

r->next=

null;//終端結點的指標域置空,或空表的頭結點指標域置空

return head;

}

注意:

上述演算法裡,動態申請新結點空間時未加錯誤處理,這對申請空間極少的程式而言不會出問題。但在實用程式裡,尤其是對空間需求較大的程式,凡是涉及動態申請空間,一定要加入錯誤處理以防系統無空間可供分配。

(4) 演算法時間複雜度

以上三個演算法的時間複雜度均為0(n)。

2.單鏈表的查詢運算

(1)按序號查詢

① 鍊錶不是隨機訪問結構

在鍊錶中,即使知道被訪問結點的序號i,也不能像順序表中那樣直接按序號i訪問結點,而只能從鍊錶的頭指標出發,順鏈域next逐個結點往下搜尋,直至搜尋到第i個結點為止。因此,鍊錶不是隨機訪問結構。

② 查詢的思想方法

計數器j置為0後,掃瞄指標p指標從鍊錶的頭結點開始順著鏈掃瞄。當p掃瞄下乙個結點時,計數器j相應地加1。當j=i時,指標p所指的結點就是要找的第i個結點。而當p指標指為null且j≠i時,則表示找不到第i個結點。

注意:

頭結點可看做是第0個結點。

③具體演算法實現

listnode* locatenode (linklist head,datatype key)

(2) 按值查詢

①思想方法

從開始結點出發,順著鏈逐個將結點的值和給定值key作比較,若有結點的值與key相等,則返回首次找到的其值為key的結點的儲存位置;否則返回null。

②具體演算法實現

listnode* locatenode (linklist head,datatype key)

3.插入運算(1)思想方法

插入運算是將值為x的新結點插入到表的第i個結點的位置上,即插入到ai-1與ai之間。

具體步驟:

(1)找到ai-1儲存位置p

(2)生成乙個資料域為x的新結點*s

(3)令結點*p的指標域指向新結點

(4)新結點的指標域指向結點ai。

(2)具體演算法實現

void insertlist(linklist head,datatype x,int i)

4.刪除運算

(1)思想方法

刪除運算是將表的第i個結點刪去。

具體步驟:

(1)找到ai-1的儲存位置p(因為在單鏈表中結點ai的儲存位址是在其直接前趨結點ai-1的指標域next中)

(2)令p->next指向ai的直接後繼結點(即把ai從鏈上摘下)

(3)釋放結點ai的空間,將其歸還給」儲存池」。

(2)具體演算法實現

void deletelist(linklist head,int i)

注意:

設單鏈表的長度為n,則刪去第i個結點僅當1≤i≤n時是合法的。

當i=n+1時,雖然被刪結點不存在,但其前趨結點卻存在,它是終端結點。因此被刪結點的直接前趨*p存在並不意味著被刪結點就一定存在,僅當*p存在(即p!=null)且*p不是終端結點(即p->next!=null)時,才能確定被刪結點存在。

迴圈鍊錶是另一種形式的鏈式存貯結構。它的特點是表中最後乙個結點的指標域指向頭結點,整個鍊錶形成乙個環。(迴圈鍊錶)

僅設尾指標的單迴圈鍊錶

用尾指標rear表示的單迴圈鍊錶對開始結點a1和終端結點an查詢時間都是o(1)。而表的操作常常是在表的首尾位置上進行,因此,實用中多採用尾指標表示單迴圈鍊錶。帶尾指標的單迴圈鍊錶可見下圖。

若在單鏈表或頭指標表示的單迴圈表上做這種鏈結操作,都需要遍歷第乙個鍊錶,找到結點an,然後將結點b1鏈到an的後面,其執行時間是o(n)。若在尾指標表示的單迴圈鍊錶上實現,則只需修改指標,無須遍歷,其執行時間是o(1)。

相應的演算法如下:

linklist

connect(linklist

a,linklist

b)

雙(向)鍊錶中有兩條方向不同的鏈,即每個結點中除next域存放後繼結點位址外,還增加乙個指向其直接前趨的指標域prior。
typedef

struct dlistnodedlistnode;

typedef dlistnode *dlinklist;

dlinklist head;

雙向鍊錶的前插和刪除本結點操作①雙鏈表的前插操作

void dinsertbefore(dlistnode *p,datatype x)

雙鏈表上刪除結點*p自身的操作

void ddeletenode(dlistnode *p)

注意:

與單鏈表上的插入和刪除操作不同的是,在雙鏈表中插入和刪除必須同時修改兩個方向上的指標。

上述兩個演算法的時間複雜度均為o(1)。

資料結構 鍊錶

鍊錶 what 就是一張鏈式儲存的表,是一種資料結構,是基礎,所以還是不要想有什麼用。具體呢?在c中就用結構體實現物件描述,然後通過函式來實現各個基本操作 c 則用類來表述,c中的結構體就可以看成c 中的類,然後通過類封裝各個操作步驟。這些操作實現後就需要 來測試,號稱demo,就是main函式裡面...

資料結構 鍊錶

一般的建立線性鍊錶有兩種 1.正序法 需要三個指標,head作為頭指標,pre作為前乙個指標,cur作為當前指標用來建立空間 2.倒序法,利用指標的插入,只需要兩個指標,不斷的往頭指標後插入新空間,不過插入的越早,離頭指標越遠,也就越後面輸出 1.線性鍊錶的建立及查詢刪除 include inclu...

資料結構 鍊錶

ifndef link h define link h include include includeusing namespace std templatestruct linknode 鍊錶結點類定義 linknode const t item,linknode ptr null 初始化 tem...