第一次嘗試
//這是 .h 部分的**
#pragma once
//使用這種方式來重新命名資料型別,這樣可以很方便的修改後續資料的資料型別,相當於#define的作用
typedef
int listtype;
//建立資料節點
typedef
struct listnode listnode;
//建立頭結點
typedef
struct listheadlisthead;
//包含所有函式的宣告
//單鏈表初始化
void
listinit
(listhead* list)
;// 動態申請乙個節點
listnode*
buylistnode
(listtype val)
;// 單鏈表列印
void
listprint
(listhead* list)
;// 單鏈表尾插
void
listpushback
(listhead* list, listtype val)
;// 單鏈表尾刪
void
listpopback
(listhead* list)
;// 單鏈表頭插
void
listpushfront
(listhead* list, listtype val)
;// 單鏈表頭刪
void
listpopfront
(listhead* list)
;// 單鏈表查詢
listnode*
slistfind
(listhead* list, listtype val)
;// 單鏈表在pos位置之後插入x
void
listinsertafter
(listnode* pos, listtype val)
;// 單鏈表刪除pos位置之後的值
void
listeraseafter
(listnode* pos)
;//單鏈表的大小
intlistsize
(listhead* list)
;// 單鏈表的銷毀
void
listdestory
(listhead* list)
;
//這是 .c 部分的**
#include
#include
#include
"list.h"
//單鏈表初始化
void
listinit
(listhead* list)
//將_head初始化為null
list->_head =
null;}
// 動態申請乙個節點
listnode*
buylistnode
(listtype val)
//申請成功就將val賦給_date,並將_next初始化為null
ret->_date = val;
ret->_next =
null
;return ret;
}// 單鏈表列印
void
listprint
(listhead* list)
listnode* node = list->_head;
//遍歷,如果不是最後乙個節點,就列印資料
while
(node !=
null
)printf
("\n");
}// 單鏈表尾插
void
listpushback
(listhead* list, listtype val)
//如果是空鍊錶,就在頭指標後面插入資料
if(list->_head ==
null
)else
//插入資料
tail->_next =
buylistnode
(val);}
}// 單鏈表尾刪
void
listpopback
(listhead* list)
listnode* tail = list->_head;
listnode* temp =
null
;//遍歷,找到最後乙個節點
while
(tail->_next !=
null
)//釋放最後乙個節點空間
free
(tail)
;//如果只有乙個資料,那麼就刪除頭指標,修改頭指標指向
if(temp ==
null
)//如果不止乙個資料,那就修改倒數第二個_next指標指向
else
}// 單鏈表頭插
void
listpushfront
(listhead* list, listtype val)
//如果是空表,就直接在頭節點後面插入資料
if(list->_head ==
null
)//如果不是空表,先保留第乙個節點,然後讓頭指標指向新申請的節點,然後讓新申請的節點指向保留的節點
else
}// 單鏈表頭刪
void
listpopfront
(listhead* list)
//只有乙個元素和有乙個以上的元素,情況其實都是一樣的,所以不用分情況討論,大家可以體會一下
listnode* node = list->_head;
listnode* temp =
null
; temp = node->_next;
//釋放頭指標
free
(node)
;//將頭指標指向原來的第二個節點,若原來只有乙個節點,那麼原來的第二個節點為null,所以正好將頭指標指向null
list->_next = temp;
}// 單鏈表查詢
listnode*
slistfind
(listhead* list, listtype val)
listnode* next = list->_head;
//使用do while語句,對獲取到的當前節點進行資料判斷,如果是要找的,就返回當前節點,如果不是,就指向下乙個節點
while
(next !=
null
)//如果不是,就更新指向下乙個節點
else
}//如果沒有找到就會返回null
return
null;}
// 單鏈表在pos位置之後插入x,這裡不能直接在pos位置插入,因為這是單向的,所以你無法獲取到上乙個指標
void
listinsertafter
(listnode* pos, listtype val)
// 單鏈表刪除pos位置之後的值,不能直接刪除,原因也和上面的一樣,直接刪除的話,鍊錶就斷了
void
listeraseafter
(listnode* pos)
//暫存pos下乙個節點為node
listnode* node = pos->_next;
//保留node節點的下乙個指向為next(無論是否為null)
listnode* next = node->_next;
//刪除node節點
free
(node)
;//將pos指向next位置,若next為null,則pos為最後乙個節點了
pos->_next = next;
}//單鏈表的大小
intlistsize
(listhead* list)
//設定計數器
int count =0;
listnode* next = list->_head;
//遍歷,每找到乙個節點,count就++
while
(next !=
null
)return count;
}// 單鏈表的銷毀
void
listdestory
(listhead* list)
listnode* node = list->_head;
//遍歷,若為空指標,就結束迴圈
while
(node)
//在將鍊錶全部釋放為空之後,將頭指標賦為null,保證安全性
list->_head =
null;}
intmain()
這是單鏈表的建立**,此單鏈表是帶頭結點、單向、不迴圈的鍊錶,對鍊錶的每乙個功能進行了介面實現,封裝成函式,方便使用者使用;
在功能的實現中,對於在任意位置插入/刪除資料不能再此單鏈表中實現,只能在任意位置的下乙個位置插入/刪除資料,因為這是單向的鍊錶,無法獲得指向該節點的指標,所以不能在插入/刪除之後將鍊錶連起來,會導致鍊錶斷鏈;後面還會進行帶頭結點、雙向、迴圈鍊錶的實現,上面問題在這種鍊錶中就可以得到很好的解決。
發表於 2020-12-08 17:24
建立鍊錶(帶頭 雙向 迴圈)
第一次嘗試 這是 h 部分的 pragma once 使用這種方式來重新命名資料型別,這樣可以很方便的修改後續資料的資料型別,相當於 define的作用 typedef int listtype 建立資料結點 typedef struct listnode listnode 建立頭結點 typede...
資料結構 鍊錶 帶頭結點的單向迴圈鍊錶
帶頭結點的單向迴圈鍊錶 include include include headlist.h 功能 建立乙個空鍊錶 引數 無 返回值 失敗返回null 成功返回頭結點的位址 list createlklist list first null list last null list n 0 現在還是空...
鍊錶 帶頭結點的雙向迴圈鍊錶
還需改進 creat node這個函式應有返回型別,來判斷新建結點是否成功,不然主函式中不管成不成功都會訪問該節點成員。改了這個函式,在主函式中create node後要判斷是否成功,不成功就提示並退出函式,退出前別忘了還要釋放鍊錶!同時create link這個函式中也要判斷head是否申請成功,...