C語言實現鍊錶(包含單鏈表和雙向鍊錶各項操作)

2021-10-01 03:35:07 字數 4265 閱讀 6036

筆者通過c語言簡單實現了單鏈表和雙向鍊錶的各類操作(增,刪,查(包含在刪操作的實現內))

文章最後有原始碼~~~~~

改 的操作基於增的操作,較為簡單,就不另外實現了。。。

基本功能如下:

1.基本實現了鍊錶的插入:

a.尾插法,b.頭插法,c.指定位置插入

2.指定值的節點的刪除

3.指定值的查詢(包含在刪除操作的實現**內,所以就沒有單獨通過函式實現)

4.鍊錶的列印

鍊錶的概念:

鍊錶是一種非連續、非順序的儲存結構,資料元素的邏輯順序是通過鍊錶中的指標鏈結次序實現的。鍊錶由一系列結點(鍊錶中每乙個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:乙個是儲存資料元素的資料域,另乙個是儲存下乙個結點位址的指標域(雙向鍊錶則會有 next 域和 pre 域 分別指向下乙個和上乙個節點)。

如下圖所示:

說明:其中 size 域記錄了鍊錶內存放元素的個數

head 域指向鍊錶的頭節點

tail 域指向鍊錶的尾節點

type 表示鍊錶的型別(1 為單鏈表 ,2 為雙向鍊錶)

**結構體說明:

node節點定義:

typedef

struct node

node;

利用typedef 命名節點 node

——以後宣告時就不用再struct node p ; 了, 直接node p ;即可

每個節點 包含 element 資料域(這裡定位int),next指標,pre指標。

鍊錶變數結構體定義:

typedef

struct list

list;

每個list 型別的變數 即代表乙個鍊錶

該變數包含size,type,tail,head域(詳細功能**注釋有說明)

部分功能函式說明(具體原理限於篇幅,不再詳述):

煉表頭插法實現:

void

insert_head

(list * l ,element key)

//頭插法 即每次插入的元素放到第一位

else

l->size +=1

;}

接受element型別的引數,並為其開闢節點,將其插入到鍊錶的頭部位置。

在插入時不會因為鍊錶型別而導致實現有所不同

——即在實現頭插法和尾插法時單向鍊錶和雙向鍊錶差異不大

尾插法實現:

void

insert_tail

(list *l ,element key)

// 尾插法 即每次插入的元素放到最後一位

else

l->size +=1

;}

在指定位置插入節點功能:

void

insert_loc

(list *l , element key ,

int position)

if(position ==1)

else

l->size +=1

;}

實現更為複雜

因為將節點插入到第一的位置需要改變head的位址,插入到最後位置則要改變tail的位址,而且在中間的插入與前兩者情況不同。

——更詳細的說明請看注釋。

指定值所在節點的刪除:

void

del_node

(list *l ,element key)

else

if(l->type ==1)

//如果是單鏈表

else

if(l->type ==2)

//如果是雙向鍊錶

} p=p->next;}}

l->size -=1

;}

因為特殊的結構,在刪除頭節點和尾結點都涉及 head 與 tail 值的更新。

同時單鏈表和雙向鍊錶各自的操作又有所不同。

所以實現**涉及到許多的特判較為繁瑣(筆者能力有限,如有更好的方法,歡迎分享)

鍊錶的列印:

void

print_list

(list *l)

if(l->type ==2)

printf

("\n");

}}

會根據鍊錶的型別而做相應的列印

釋放鍊錶:

void

destory_list

(list *l)

free

(l);

}

釋放動態開闢的記憶體

最終源**如下:

#include

#include

typedef

int element;

typedef

struct node

node;

typedef

struct list

list;

list *

init_list

(int type)

void

insert_head

(list * l ,element key)

//頭插法 即每次插入的元素放到第一位

else

l->size +=1

;}void

insert_tail

(list *l ,element key)

// 尾插法 即每次插入的元素放到最後一位

else

l->size +=1

;}void

insert_loc

(list *l , element key ,

int position)

if(position ==1)

else

l->size +=1

;}void

del_node

(list *l ,element key)

else

if(l->type ==1)

//如果是單鏈表

else

if(l->type ==2)

//如果是雙向鍊錶

} p=p->next;}}

l->size -=1

;}//如果判斷為雙向鍊錶 就輸出兩種列印(從頭到尾,從尾到頭)

void

print_list

(list *l)

if(l->type ==2)

printf

("\n");

}}void

destory_list

(list *l)

// free(l->head);

free

(l);

}int

main()

; element key =10;

list *l =

init_list(2

);//接收引數 1代表單向鍊錶 2代表雙向鍊錶

int i =0;

for(i=

0; i<

sizeof

(a)/

sizeof

(element)

; i++

)insert_loc

(l,30,3

);// 將 30 插入到三號位置

insert_loc

(l,10,1

);// 將 10 插入一號位置

insert_loc

(l,20

,l->size+1)

;// 將 20 插入到最後

print_list

(l);

del_node

(l,key)

;print_list

(l);

printf

("\ntype:%d size:%d\n"

, l->type,l->size)

;destory_list

(l);

return0;

}

執行截圖:

謝謝閱讀!

雙向鍊錶C語言實現

ifndef stdlist h define stdlist h typedef struct tagstdnode stdnode,lpstdnode typedef struct tagstdlist stdlist,lpstdlist 鍊錶資料結構 struct tagstdnode 鍊錶節...

c語言實現雙向鍊錶

單向鍊錶有一定的缺陷,其中乙個就是只能一條路走到黑,只能前進不能後退,但雙向鍊錶就解決了這一問題 include include typedef struct node node,linklist void create list tail linklist l 頭插法建立 void create ...

C語言實現雙向鍊錶

1.定義兩個結構體,乙個表示鍊錶的乙個單元,另乙個表示鍊錶的頭結點 2.鍊錶的初始化 必須讓頭結點的next和prev指向自己 清除 不刪除頭結點 銷毀 刪除頭結點 3.增操作 每次增加需要開闢乙個單元,所以直接建立乙個函式用來建立單元 頭插 尾插 pos結點之前插 4.刪操作 分為三種 刪除pos...