筆者通過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...