C语言实现通用链表初步(二)
接著上次的內(nèi)容,我們繼續(xù)!
還是無(wú)頭單向非循環(huán)鏈表。假如要?jiǎng)h除某個(gè)節(jié)點(diǎn),如何實(shí)現(xiàn)?
//刪除成功返回0,失敗返回-1 int slist_del(struct node_info *node, struct slist_info *info) {assert(info != NULL && node != NULL);assert(!slist_is_empty(info));if(node==info->first)//如果要?jiǎng)h除的就是第一個(gè)節(jié)點(diǎn){info->first = node->next;free(node);return 0;}//如果不是第一個(gè),那么是哪個(gè)呢?要?jiǎng)h除必須先找到,可是找到就可以了嗎?//因?yàn)槭菃蜗蜴湵?#xff0c;我們只能知道這個(gè)節(jié)點(diǎn)的后面那個(gè),而不知道前面是誰(shuí),那怎么刪除呢?//所以,在遍歷的過(guò)程中,還要把前面的一個(gè)節(jié)點(diǎn)保存起來(lái) else{struct node_info *pre = info->first;struct node_info *cur = pre->next;while(cur!=NULL&&cur!=node){pre = pre->next;cur = cur->next;}if(cur==NULL)return -1; // the node to delete is not in the listpre->next = cur->next;//deletefree(cur);return 0;}}假設(shè)有個(gè)程序員很粗心,讓最后一個(gè)節(jié)點(diǎn)的next指針指向了鏈表中的某一個(gè)節(jié)點(diǎn),你能檢查出來(lái)嗎?
1----2----3----4----5----6----7----8----9
? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? ? ? ? ? ? ? ? ? ?|----------------------|
比如這個(gè)圖,1是第一個(gè),9的后面是5,構(gòu)成了一個(gè)環(huán)。
思路是這樣的:假設(shè)2個(gè)人,一個(gè)人每次走1步,另一個(gè)每次走2步。同時(shí)出發(fā),如果有環(huán)存在,那么這兩個(gè)人肯定會(huì)相遇的!因?yàn)閮蓚€(gè)人都要在圈里面繞,步長(zhǎng)差1,那么快的那個(gè)肯定會(huì)追趕慢的那個(gè),總會(huì)追上的!------此思路我們稱(chēng)為“追趕法”!
int slist_is_dead_loop(struct slist_info *info) {assert(info != NULL);assert(!slist_is_empty(info));assert(info->first->next!=NULL);//節(jié)點(diǎn)數(shù)不少于兩個(gè)struct node_info *slow = info->first;struct node_info *fast = info->first;while (fast!= NULL && fast->next != NULL) { //che 2014.4.28fast = fast->next->next;slow = slow->next;if (fast == slow) {break;//相遇}}if (fast != slow) {return 0; //無(wú)死環(huán)}//此時(shí)相遇。怎么求環(huán)的長(zhǎng)度呢?//fast固定,每次移動(dòng)1步slow,再次相遇的時(shí)候,移動(dòng)的步數(shù)就是環(huán)的長(zhǎng)度int step = 1;slow = slow->next;while(fast!=slow){slow = slow->next;++step;}printf("the circle = %d\n",step);//怎么求環(huán)前面那段鏈子的長(zhǎng)度?O----------------------------------------E-----------------------A-------
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |------------------------------- |
如圖,假設(shè)E點(diǎn)是環(huán)的起點(diǎn),設(shè)OE長(zhǎng)為x,環(huán)的長(zhǎng)度是L.
我們安排一個(gè)場(chǎng)景,甲乙兩個(gè)人,乙先出發(fā),走到A點(diǎn)時(shí)候,甲出發(fā)了,兩個(gè)人的速度是一樣的,在E點(diǎn)的時(shí)候,兩人相遇了!這時(shí)候甲走的步數(shù)就是鏈子的長(zhǎng)度!問(wèn)題是A點(diǎn)是哪里呢?
我們可以列出等式 ? x+L = 乙先走的(OA)+乙后走的(也就是甲走的x)
所以,OA=L
也就是說(shuō),先讓乙走L步,然后兩個(gè)人都走,相遇的時(shí)候,甲走的就是所求,接著上面的代碼
//設(shè)環(huán)的長(zhǎng)度為L(zhǎng),讓兩個(gè)人都回到起點(diǎn),先讓P2向前走L步。//然后p1,p2每次往前走一步,當(dāng)他們相遇的時(shí)候,p1移動(dòng)的步數(shù)就是所求fast = slow = info->first;while(step--)fast = fast->next; //P2向前走L步step = 0;while(fast!=slow){slow = slow->next;fast = fast->next;++step;}printf("the line = %d\n",step);//鏈子的長(zhǎng)度return 1; //有死環(huán) }關(guān)于測(cè)試代碼,下次再說(shuō)。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
總結(jié)
以上是生活随笔為你收集整理的C语言实现通用链表初步(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 前公司让回去上班?
- 下一篇: 后疫情时代,那些迎来爆发机会的产业