日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

单链表插入元素 注释 c语言,数据结构之无头单链表的相关练习题——C语言实现(详细注释)...

發(fā)布時(shí)間:2025/3/12 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单链表插入元素 注释 c语言,数据结构之无头单链表的相关练习题——C语言实现(详细注释)... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文中所用到的相關(guān)鏈表操作實(shí)現(xiàn)均在我上篇博客中:https://blog..net/haoziai905/article/details/87099287

1.刪除無(wú)頭單鏈表的非尾結(jié)點(diǎn)

這道題的重點(diǎn)就在于最后的非尾結(jié)點(diǎn)上,既然是非尾結(jié)點(diǎn),則說(shuō)明其下一個(gè)結(jié)點(diǎn)必定不為空。而我們通常所使用的刪除節(jié)點(diǎn)的方法都需要知道所要?jiǎng)h除節(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn),但是要找到鏈表中一個(gè)結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)并容易,只能通過(guò)遍歷鏈表去尋找,但是遍歷鏈表的代價(jià)是非常大的。所以我們需要一個(gè)方法,讓我們不需要遍歷鏈表就能刪除這個(gè)結(jié)點(diǎn)。

首先,我們需要明白刪除一個(gè)結(jié)點(diǎn)的目的是什么。我們刪除一個(gè)結(jié)點(diǎn)的目的是為了刪除這個(gè)結(jié)點(diǎn)中所儲(chǔ)存的數(shù)據(jù),而不是一定要?jiǎng)h除這個(gè)結(jié)點(diǎn)才行。所以我們可以通過(guò)交換要?jiǎng)h除結(jié)點(diǎn)與下一個(gè)結(jié)點(diǎn)的數(shù)據(jù),再將下一個(gè)結(jié)點(diǎn)刪除就好了。而不需要去查找要?jiǎng)h除結(jié)點(diǎn)的上一個(gè)結(jié)點(diǎn)。

//刪除無(wú)頭單鏈表的非尾結(jié)點(diǎn)

void DelNodeNotTail(pNode pos)

{

assert(pos);

assert(pos->next);

//交換pos結(jié)點(diǎn)與pos下一結(jié)點(diǎn)的元素

pNode cur = pos->next;

pos->data = cur->data;

pos->next = cur->next;

//刪除pos結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)

free(cur);

cur = NULL;

}

2.在無(wú)頭單鏈表的一個(gè)位置前插入一個(gè)元素

這個(gè)題與上一個(gè)題類(lèi)似,插入元素也是需要知道要插入位置的前一個(gè)結(jié)點(diǎn)才行,但是遍歷鏈表的代價(jià)太大。所以我們也可以通過(guò)上一題交換結(jié)點(diǎn)中元素的方法來(lái)實(shí)現(xiàn),在該位置后插入一個(gè)新結(jié)點(diǎn),然后交換兩個(gè)結(jié)點(diǎn)中的元素即可。

//在無(wú)頭單鏈表的一個(gè)結(jié)點(diǎn)前插入一個(gè)結(jié)點(diǎn)

void InsertNode(pNode pos, DataType data)

{

assert(pos);

pNode cur = pos->next;//保存pos的下一結(jié)點(diǎn)位置

DataType tmp = pos->data;//保存pos結(jié)點(diǎn)的元素

//在pos位置后插入一個(gè)新結(jié)點(diǎn),并交換pos結(jié)點(diǎn)與新結(jié)點(diǎn)的元素

pos->next = BuyNode(data);

pos->data = data;

pos->next->data = tmp;

//將鏈表重新連接起來(lái)

pos->next->next = cur;

}

3.約瑟夫環(huán)

約瑟夫環(huán)是什么呢?約瑟夫環(huán)(約瑟夫問(wèn)題)是一個(gè)數(shù)學(xué)的應(yīng)用問(wèn)題:已知n個(gè)人(以編號(hào)1,2,3...n分別表示)圍坐在一張圓桌周?chē)木幪?hào)為k的人開(kāi)始報(bào)數(shù),數(shù)到m的那個(gè)人出列;他的下一個(gè)人又從1開(kāi)始報(bào)數(shù),數(shù)到m的那個(gè)人又出列;依此規(guī)律重復(fù)下去,直到圓桌周?chē)娜巳砍隽小N覀冃枰ㄟ^(guò)代碼來(lái)模擬約瑟夫環(huán)的過(guò)程,以此來(lái)知道誰(shuí)會(huì)留到最后。

//約瑟夫環(huán)

void JosephusCycle(pList* pplist, int k)

{

pNode cur = *pplist;

pNode del = NULL;

//當(dāng)cur==cur->next時(shí)說(shuō)明只剩下一個(gè)人了

while (cur != cur->next)

{

for (int i = 1; i < k; i++)

{

cur = cur->next;

}

printf("The %d is die!\n", cur->data);

del = cur->next->next;//保存cur的下下一個(gè)結(jié)點(diǎn)

cur->data = cur->next->data;//交換cur結(jié)點(diǎn)和下一結(jié)點(diǎn)的元素

free(cur->next);//刪除cur的下一結(jié)點(diǎn)

cur->next = del;//連接起鏈表

del = NULL;

}

*pplist = cur;

printf("The %d is live!\n", cur->data);

}

4.逆序單鏈表

要想將單鏈表逆序有兩種方法,第一個(gè)方法就是通過(guò)三個(gè)指針實(shí)現(xiàn),還有一種方法就是通過(guò)頭插來(lái)實(shí)現(xiàn)。當(dāng)我們將一個(gè)鏈表的結(jié)點(diǎn)從頭到尾一個(gè)一個(gè)的頭插到另一個(gè)新鏈表上時(shí),這時(shí)新產(chǎn)生的鏈表就是第一條鏈表逆序后的樣子。

//逆序鏈表:三指針?lè)?/p>

void ReverseList(pList* pplist)

{

assert(pplist);

//當(dāng)鏈表為空鏈表或者鏈表中只有一個(gè)元素時(shí),不需要逆序

if ((*pplist) == NULL || (*pplist)->next == NULL)

{

return;

}

pNode frist = *pplist;

pNode second = frist->next;

pNode third = second->next;

while (second != NULL)

{

second->next = frist;

frist = second;

second = third;

if (third != NULL)

{

third = third->next;

}

}

(*pplist)->next = NULL;

*pplist = frist;

}

//逆序鏈表:頭插法

void ReverseList(pList* pplist)

{

assert(pplist);

if ((*pplist) == NULL || ((*pplist)->next == NULL))

{

return;

}

pList pHead = NULL;

pNode cur = *pplist;

pNode tmp = cur->next;

while (cur)

{

//頭插

if (pHead == NULL)

{

pHead = cur;

}

else

{

cur->next = pHead;

pHead = cur;

cur = tmp;

if (tmp)

{

tmp = tmp->next;

}

}

}

(*pplist)->next = NULL;

*pplist = pHead;

}

5.冒泡排序

冒泡排序時(shí)最簡(jiǎn)單的一種排序方法,實(shí)現(xiàn)起來(lái)也并不復(fù)雜,但是我們通常所實(shí)現(xiàn)的冒泡排序都是通過(guò)數(shù)組或者是順序來(lái)實(shí)現(xiàn)的,那么在鏈表中我們應(yīng)該如何實(shí)現(xiàn)冒泡排序呢?

//冒泡排序

void BubbleSort(pList plist)

{

if (NULL == plist)

{

return;

}

pNode tail = NULL;

while (tail != plist)

{

pNode cur = plist;

pNode next = cur->next;

int flag = 0;//設(shè)置標(biāo)志位,提高排序效率

while (next != tail)

{

//升序排列

if (next->data < cur->data)

{

DataType tmp = next->data;

next->data = cur->data;

cur->data = tmp;

flag = 1;//如果單趟排序中發(fā)生了交換則將標(biāo)志位置1

}

else

{

cur = next;

next = next->next;

}

}

//標(biāo)志位為0則說(shuō)明為發(fā)生元素交換,則剩下的元素已經(jīng)有序,不需要排序,直接返回

if (flag == 0)

{

return;

}

tail = cur;

}

}

6.合并兩個(gè)有序鏈表,合并后依然有序

只需要一一對(duì)比兩個(gè)鏈表中元素的大小,然后按照我們所想要的順序?qū)⒋蟮脑鼗蛘咝〉脑匚膊迦胄骆湵碇屑纯伞?/p>

//合并兩個(gè)有序鏈表合并后仍然有序

pList Merge(pList plist1, pList plist2)

{

//1.兩個(gè)鏈表是一條鏈表

//2.兩條鏈表中有一條為空

//出現(xiàn)上面兩種情況都不需要合并鏈表

if (plist1 == plist2)

{

return plist1;

}

if (plist1 == NULL)

{

return plist2;

}

if (plist2 == NULL)

{

return plist1;

}

pList newlist = NULL;

pList cur = NULL;

while (plist1 != NULL && plist2 != NULL)

{

//比較兩條鏈表當(dāng)前第一個(gè)結(jié)點(diǎn)元素的大小

//升序排列則將元素較小的結(jié)點(diǎn)接在新鏈表后

if (plist1->data < plist2->data)

{

if (newlist == NULL)

{

newlist = plist1;

cur = newlist;

}

else

{

cur->next = plist1;

cur = cur->next;

}

plist1 = plist1->next;

}

else

{

if (newlist == NULL)

{

newlist = plist2;

cur = newlist;

}

else

{

cur->next = plist2;

cur = cur->next;

}

plist2 = plist2->next;

}

}

//當(dāng)其中一個(gè)鏈表已經(jīng)為空時(shí),直接將另一條鏈表的整條鏈表接在新鏈表后即可

if (plist1 == NULL && plist2 != NULL)

{

cur->next = plist2;

}

else if (plist1 != NULL && plist2 == NULL)

{

cur->next = plist1;

}

return newlist;

}

7.只遍歷鏈表一遍,找到中間結(jié)點(diǎn)

//只遍歷鏈表一遍,找到中間結(jié)點(diǎn)

pNode FindMidNode(pList plist)

{

//快慢指針?lè)?#xff0c;快指針?biāo)俣仁锹羔標(biāo)俣鹊膬杀?/p>

//當(dāng)快指針走到鏈表尾時(shí),則慢指針正好走到鏈表的中間位置

pNode fast = plist;

pNode slow = plist;

while (fast != NULL && fast->next != NULL)

{

slow = slow->next;

fast = fast->next->next;

}

return slow;

}

8.只遍歷一遍找到鏈表的倒數(shù)第K個(gè)結(jié)點(diǎn)

//只遍歷一遍找到鏈表的倒數(shù)第K個(gè)結(jié)點(diǎn)

pNode FindLastKNode(pList plist, int k)

{

if (plist == NULL)

{

return NULL;

}

int count = k;

pNode fast = plist;

pNode slow = plist;

//快指針先走K步

while (count--)

{

//如果快指針已經(jīng)為空則說(shuō)明鏈表中不足K個(gè)元素

if (fast == NULL)

{

return NULL;

}

fast = fast->next;

}

//快慢指針一起走,當(dāng)快指針為空時(shí),慢指針指的就是倒數(shù)第K個(gè)元素

while (fast != NULL)

{

fast = fast->next;

slow = slow->next;

}

return slow;

}

以上代碼均通過(guò)VS2017環(huán)境測(cè)試。

總結(jié)

以上是生活随笔為你收集整理的单链表插入元素 注释 c语言,数据结构之无头单链表的相关练习题——C语言实现(详细注释)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。