<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
連結直達:
題目:
思路:
此題要綜合考慮多種情況,常規情況就如同範例1,有多個節點,並且val不連續,但是非常規呢?當val連續呢?當頭部就是val呢?所以要分類討論
常規情況:
需要定義兩個指標prev和cur,cur指向第一個資料,prev指向cur的前一個。依次遍歷cur指向的資料是否為val,若是,則把prev的下一個節點指向cur的下一個節點上,cur=cur->next,prev跟著cur一起走,直到cur走到NULL
連續val:
當我們仔細觀察下,不難發現,在常規情況下是可以解決連續val的,但是頭部val就不可了
頭部val:
此時除了剛才定義的兩個指標prev和cur外,還要有個head指向頭部,當頭部是val時,將cur指向下一個位置,head跟著一起動,直到cur指向的資料不為val時,將head賦給prev。此時剩餘的就按常規處理即可。
程式碼如下:
struct ListNode* removeElements(struct ListNode* head, int val){ struct ListNode*cur=head; struct ListNode*prev=NULL; while(cur) { if(cur->val!=val) { prev=cur; cur=cur->next; } else { struct ListNode*next=cur->next; if(prev==NULL) { free(cur); cur=next; head=next; } else { prev->next=cur->next; free(cur); cur=prev->next; } } } return head; }
連結直達:
題目:
思路:
法一:三指標翻轉方向
定義三個指標n1,n2,n3分別用來指向NULL,第一個資料,第二個資料。讓n2的next指向n1,把n2賦給n1,再把n3賦給n2,再執行n3=n3->next的操作,接下來重複上述操作,直到n2指向空即可。但是要注意,要先判斷該連結串列是否為NULL,如果是,則返回NULL,此外,還要保證當n3為空時就不要動了,直接把n3賦給n2即可。
程式碼如下:
struct ListNode* reverseList(struct ListNode* head){ if(head==NULL) { return NULL; } struct ListNode*n1=NULL; struct ListNode*n2=head; struct ListNode*n3=n2->next; while(n2) { n2->next=n1; n1=n2; n2=n3; if(n3) { n3=n3->next; } } return n1; }
法二:頭插
此法就需要再建立一個連結串列了,建立一個新的頭部newhead指向NULL,再定義一個指標cur指向原連結串列第一個資料,注意還得定義一個指標next指向cur的下一個節點。遍歷原連結串列,把節點取下來頭插到newhead所在的連結串列。每次更新newhead賦給cur,如圖所示:
程式碼如下:
struct ListNode* reverseList(struct ListNode* head){ if(head==NULL) { return NULL; } struct ListNode*cur=head; struct ListNode*next=cur->next; struct ListNode*newhead=NULL; while(cur) { cur->next=newhead; newhead=cur; cur=next; if(next) { next=next->next; } } return newhead; }
連結直達:
題目:
思路:
快慢指標
這道題要注意奇偶數,如果為奇數,如範例1,那麼中間節點值就是3,反之偶數如範例2,返回第二個中間節點。此題我們定義兩個指標slow和fast都指向第一個資料的位置,區別在於讓slow一次走1步,fast一次走2步。當fast走到尾指標時,slow就是中間節點
程式碼如下:
struct ListNode* middleNode(struct ListNode* head){ struct ListNode*slow=head; struct ListNode*fast=head; while(fast&&fast->next) { slow=slow->next; fast=fast->next->next; } return slow; }
連結直達:
題目:
思路:
快慢指標
定義兩個指標slow和fast,讓fast先走k步,再讓slow和fast同時走,當fast走到尾部時,slow就是倒數第k個,因為這樣的話slow和fast的差距始終是k個,當fast走到空時結束。此題同樣可以走k-1步,不過當fast走到尾部時結束,也就是fast的下一個節點指向空時結束,都一樣。先拿走k步舉例,如圖所示:
程式碼如下:
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) { // write code here struct ListNode*fast=pListHead; struct ListNode*slow=pListHead; while(k--) { //if判斷,防止k大於連結串列的長度 if(fast==NULL) return NULL; fast=fast->next; } while(fast) { fast=fast->next; slow=slow->next; } return slow; }
連結直達:
題目:
思路:
法一:歸併(取小的尾插)--- 帶頭節點
假設新連結串列的頭叫head並指向NULL,還需要定義一個指標tail來方便後續的找尾,依次比較list1和list2節點的值,把小的放到新連結串列head上,並更新tail,再把list1或list2更新一下。當list1和list2兩個連結串列中一個走到空時,直接把剩下的連結串列所有剩下的元素拷進去即可
程式碼如下:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){ //檢查list1或list2一開始就為NULL的情況 if(list1==NULL) { return list2; } if(list2==NULL) { return list1; } struct ListNode*head=NULL; struct ListNode*tail=head; while(list1&&list2) { if(list1->val<list2->val) { if(tail==NULL) { head=tail=list1; } else { tail->next=list1; tail=list1; } list1=list1->next; } else { if(tail==NULL) { head=tail=list2; } else { tail->next=list2; tail=list2; } list2=list2->next; } } //當list1和list2其中一個走到空的情況 if(list1==NULL) { tail->next=list2; } else { tail->next=list1; } return head; }
法二:哨兵位的頭節點
解釋下帶頭節點:
比如說同樣一個連結串列存1,2,3。不帶頭節點只有這三個節點,head指向1。而帶頭節點的同樣存3個值,不過有4個節點,head指向頭部這個節點,這個節點不儲存有效資料
帶頭結點有如下好處,不用判斷head和tail是否為空了,也不用判斷list1和list2是否為空了,會方便不少。和上述思路一樣,取小的下來尾插,直接連結到tail後面即可。但是要注意返回的時候要返回head的next,因為題目給的連結串列是不帶頭的,而head本身指向的就是那個頭,所以要返回下一個。
程式碼如下:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) { struct ListNode* head = NULL, * tail = NULL; head = tail = (struct ListNode*)malloc(sizeof(struct ListNode)); head->next = NULL; while (list1 && list2) { if (list1->val < list2->val) { tail->next = list1; tail = list1; list1 = list1->next; } else { tail->next = list2; tail = list2; list2 = list2->next; } } //當list1和list2其中一個走到空的情況 if (list1 == NULL) { tail->next = list2; } else { tail->next = list1; } struct ListNode* list = head->next; free(head); head = NULL return list; }
連結直達:
題目:
思路:
定義兩個連結串列lesshead和greaterhead。遍歷原連結串列,把 < x 的插入到連結串列1,把 > x 的插入到連結串列2,最後再把連結串列1和連結串列2連結起來。在定義兩個尾指標以跟進連結串列1和2新增元素
程式碼如下:
class Partition { public: ListNode* partition(ListNode* pHead, int x) { // write code here struct ListNode* lessHead, * lessTail, * greaterHead, * greaterTail; lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode)); greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode)); lessTail->next = greaterTail->next = NULL; struct ListNode* cur = pHead; while (cur) { if (cur->val < x) { lessTail->next = cur; lessTail = lessTail->next; } else { greaterTail->next = cur; greaterTail = greaterTail->next; } cur = cur->next; } //合併 lessTail->next = greaterHead->next; greaterTail->next = NULL; struct ListNode* list = lessHead->next; free(lessHead); free(greaterHead); return list; } };
到此這篇關於C語言實題講解快速掌握單連結串列上的文章就介紹到這了,更多相關C語言 單連結串列內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45