C語(yǔ)言實(shí)現(xiàn)無(wú)頭單向鏈表的示例代碼
一、易錯(cuò)的接口實(shí)現(xiàn)
1.1 新節(jié)點(diǎn)開(kāi)辟函數(shù)
由于創(chuàng)建一個(gè)新節(jié)點(diǎn)是頻繁的操作,所以封裝為一個(gè)接口最佳。
鏈表節(jié)點(diǎn)的屬性有:(1)數(shù)值。(2)指向下一個(gè)節(jié)點(diǎn)的地址。(3)自身地址。
static SLTNode* BuySListNode(SLTDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
//開(kāi)辟失敗
if (newnode == NULL)
{
printf("malloc fail\n");
exit(-1);
}
//初始化
newnode->data = x;
newnode->next = NULL;
return newnode;
}
數(shù)值和next地址都由此函數(shù)初始化,自身地址則由函數(shù)的返回值返回。
要注意使用malloc函數(shù)時(shí),可能存在開(kāi)辟空間失敗的情況,這時(shí)會(huì)返回NULL。
1.2 尾插
尾插的難點(diǎn)在于存在特殊情況。
當(dāng)對(duì)非空鏈表和空鏈表進(jìn)行尾插時(shí),所需代碼不同。
對(duì)非空鏈表尾插時(shí),算法是:找到此鏈表的尾部,即遍歷此鏈表,直至自定義的結(jié)構(gòu)體指針tail的下一個(gè)節(jié)點(diǎn)為NULL,結(jié)束遍歷。在tail的后面插入一個(gè)新節(jié)點(diǎn)。
對(duì)空鏈表尾插時(shí),算法是:直接把新節(jié)點(diǎn)作為鏈表的頭節(jié)點(diǎn)。
void SListPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
//找尾
SLTNode* tail = *pphead;
if (tail == NULL)
{
tail = BuySListNode(x);
*pphead = tail;
}
else
{
while (tail->next != NULL)
{
tail = tail->next;
}
SLTNode* newnode = BuySListNode(x);
tail->next = newnode;
}
}
1.3 尾刪
此接口也有特殊情況處理。
當(dāng)鏈表有一個(gè)以上的節(jié)點(diǎn)時(shí),算法:遍歷鏈表到尾部,free掉tail所在內(nèi)存,改變tail之前一個(gè)節(jié)點(diǎn)的next,為NULL。
需要一個(gè)結(jié)構(gòu)體指針變量prev來(lái)記錄tail的前一個(gè)節(jié)點(diǎn)。
當(dāng)鏈表只有一個(gè)節(jié)點(diǎn)時(shí),算法:tail一開(kāi)始就在尾部,直接free掉tail,再把prev指針(初值為NULL)賦值給頭節(jié)點(diǎn)*pphead。
如果不單獨(dú)考慮這種情況的話,會(huì)因?yàn)镹ULL->next而出現(xiàn)內(nèi)存錯(cuò)誤。
當(dāng)鏈表沒(méi)有節(jié)點(diǎn)時(shí),是不可以調(diào)用尾刪的,直接用assert函數(shù)報(bào)錯(cuò)。
void SListPopBack(SLTNode** pphead)
{
assert(pphead);
assert(*pphead);//沒(méi)有節(jié)點(diǎn)斷言報(bào)錯(cuò)
SLTNode* prev = NULL;
SLTNode* tail = *pphead;
while (tail->next != NULL)
{
prev = tail;
tail = tail->next;
}
free(tail);
tail = NULL;
if (prev != NULL)
prev->next = NULL;
else
*pphead = prev;
}
二、常見(jiàn)簡(jiǎn)單接口
2.1 打印鏈表
void SListPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
2.2 節(jié)點(diǎn)計(jì)數(shù)器
int SListSize(SLTNode* phead)
{
//計(jì)數(shù)器
int count = 0;
SLTNode* cur = phead;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}
2.3 判斷是否為空鏈表
bool SListEmpty(SLTNode* phead)
{
return phead == NULL;
}
2.4 通過(guò)值查找節(jié)點(diǎn)
SLTNode* SListFind(SLTNode* phead, SLTDataType data)
{
//通過(guò)數(shù)據(jù)查找節(jié)點(diǎn)-遍歷節(jié)點(diǎn),判斷值是否相等
SLTNode* cur = phead;
while (cur)
{
if (cur->data == data)
return cur;
cur = cur->next;
}
return NULL;
}
2.5 頭插
void SListPushFront(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = BuySListNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
2.6 頭刪
void SListPopFront(SLTNode** pphead)
{
assert(pphead);
assert(*pphead);
SLTNode* next = (*pphead)->next;
free(*pphead);
*pphead = NULL;
*pphead = next;
}
2.7 在任意節(jié)點(diǎn)后插入節(jié)點(diǎn)
void SListInsert(SLTNode* pos, SLTDataType x)
{
assert(pos);
SLTNode* newnode = BuySListNode(x);
SLTNode* next = pos->next;
pos->next = newnode;
newnode->next = next;
}
2.8 在任意節(jié)點(diǎn)后刪除節(jié)點(diǎn)
void SListErase(SLTNode* pos)
{
assert(pos);
assert(pos->next);
SLTNode* next = pos->next;
pos->next = next->next;
free(next);
next = NULL;
}
2.9 銷(xiāo)毀鏈表
void SListDestroy(SLTNode** pphead)
{
assert(pphead);
SLTNode* cur, * nextnode;
cur = *pphead;
nextnode = NULL;
while (cur)
{
nextnode = cur->next;
free(cur);
cur = nextnode;
}
*pphead = NULL;
}
三、頭文件相關(guān)內(nèi)容
3.1 引用的庫(kù)函數(shù)
#include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h>
3.2 結(jié)構(gòu)體聲明
typedef int SLTDataType;//重定義可便于修改值的數(shù)據(jù)類(lèi)型
1
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;//重定義可減少代碼冗余
到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)無(wú)頭單向鏈表的示例代碼的文章就介紹到這了,更多相關(guān)C語(yǔ)言無(wú)頭單向鏈表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語(yǔ)言實(shí)現(xiàn)帶頭雙向環(huán)形鏈表
- C語(yǔ)言超詳細(xì)講解數(shù)據(jù)結(jié)構(gòu)中雙向帶頭循環(huán)鏈表
- C語(yǔ)言實(shí)現(xiàn)帶頭雙向循環(huán)鏈表
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解單向鏈表
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之單向鏈表詳解分析
- C語(yǔ)言之單向鏈表詳解及實(shí)例代碼
- C語(yǔ)言單向鏈表的表示與實(shí)現(xiàn)實(shí)例詳解
- C語(yǔ)言實(shí)例真題講解數(shù)據(jù)結(jié)構(gòu)中單向環(huán)形鏈表
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)繪制可愛(ài)的橘子鐘表
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)繪制可愛(ài)的橘子鐘表,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下2022-12-12
C語(yǔ)言判斷字符串長(zhǎng)度的方法小結(jié)
學(xué)過(guò)C/C++的人都知道,在C/C++中并沒(méi)有提供直接獲取數(shù)組長(zhǎng)度的函數(shù),對(duì)于存放字符串的字符數(shù)組提供了一個(gè)strlen函數(shù)獲取其長(zhǎng)度,那么對(duì)于其他類(lèi)型的數(shù)組如何獲取他們的長(zhǎng)度呢?本文給大家介紹了C語(yǔ)言判斷字符串長(zhǎng)度的方法小結(jié),需要的朋友可以參考下2024-08-08
如何基于C++解決RTSP取流報(bào)錯(cuò)問(wèn)題
這篇文章主要介紹了如何基于C++解決RTSP取流報(bào)錯(cuò)問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
美化你的代碼 vb(VBS)代碼格式化的實(shí)現(xiàn)代碼
雖然VB.NET出現(xiàn)很久了,但還有好多人仍然在使用VB6。我在實(shí)現(xiàn)一些小功能的時(shí)候也喜歡用VB6,畢竟誰(shuí)都不想每天的美好心情被VS那烏龜般的啟動(dòng)速度影響2012-05-05
C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù))
cJSON是一個(gè)超輕巧的JSON解析器,本文主要介紹了C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù)),具有一定的參考價(jià)值,感興趣的可以了解一下2021-09-09
udp socket客戶端和udp服務(wù)端程序示例分享
這篇文章主要介紹了udp socket客戶端和udp服務(wù)端程序示例,需要的朋友可以參考下2014-03-03
C語(yǔ)言算法練習(xí)之?dāng)?shù)組元素排序
這篇文章主要為大家介紹了C語(yǔ)言算法練習(xí)中數(shù)組元素排序的實(shí)現(xiàn)方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,需要的可以參考一下2022-09-09
C語(yǔ)言實(shí)現(xiàn)銷(xiāo)售管理系統(tǒng)設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)銷(xiāo)售管理系統(tǒng)設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

