C語言實題講解快速掌握單鏈表上_第1頁
C語言實題講解快速掌握單鏈表上_第2頁
C語言實題講解快速掌握單鏈表上_第3頁
C語言實題講解快速掌握單鏈表上_第4頁
C語言實題講解快速掌握單鏈表上_第5頁
已閱讀5頁,還剩7頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第C語言實題講解快速掌握單鏈表上目錄1、移除鏈表元素2、反轉鏈表3、鏈表的中間節點4、鏈表中倒數第k個節點5、合并兩個有序鏈表6、鏈表分割

1、移除鏈表元素

鏈接直達:

移除鏈表元素

題目:

思路:

此題要綜合考慮多種情況,常規情況就如同示例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。此時剩余的就按常規處理即可。

代碼如下:

structListNode*removeElements(structListNode*head,intval){

structListNode*cur=head;

structListNode*prev=NULL;

while(cur)

if(cur-val!=val)

prev=cur;

cur=cur-next;

else

structListNode*next=cur-next;

if(prev==NULL)

free(cur);

cur=next;

head=next;

else

prev-next=cur-next;

free(cur);

cur=prev-next;

returnhead;

}

2、反轉鏈表

鏈接直達:

反轉鏈表

題目:

思路:

法一:三指針翻轉方向

定義三個指針n1,n2,n3分別用來指向NULL,第一個數據,第二個數據。讓n2的next指向n1,把n2賦給n1,再把n3賦給n2,再執行n3=n3-next的操作,接下來重復上述操作,直到n2指向空即可。但是要注意,要先判斷該鏈表是否為NULL,如果是,則返回NULL,此外,還要保證當n3為空時就不要動了,直接把n3賦給n2即可。

代碼如下:

structListNode*reverseList(structListNode*head){

if(head==NULL)

returnNULL;

structListNode*n1=NULL;

structListNode*n2=head;

structListNode*n3=n2-next;

while(n2)

n2-next=n1;

n1=n2;

n2=n3;

if(n3)

n3=n3-next;

returnn1;

}

法二:頭插

此法就需要再創建一個鏈表了,創建一個新的頭部newhead指向NULL,再定義一個指針cur指向原鏈表第一個數據,注意還得定義一個指針next指向cur的下一個節點。遍歷原鏈表,把節點取下來頭插到newhead所在的鏈表。每次更新newhead賦給cur,如圖所示:

代碼如下:

structListNode*reverseList(structListNode*head){

if(head==NULL)

returnNULL;

structListNode*cur=head;

structListNode*next=cur-next;

structListNode*newhead=NULL;

while(cur)

cur-next=newhead;

newhead=cur;

cur=next;

if(next)

next=next-next;

returnnewhead;

}

3、鏈表的中間節點

鏈接直達:

鏈表的中間節點

題目:

思路:

快慢指針

這道題要注意奇偶數,如果為奇數,如示例1,那么中間節點值就是3,反之偶數如示例2,返回第二個中間節點。此題我們定義兩個指針slow和fast都指向第一個數據的位置,區別在于讓slow一次走1步,fast一次走2步。當fast走到尾指針時,slow就是中間節點

代碼如下:

structListNode*middleNode(structListNode*head){

structListNode*slow=head;

structListNode*fast=head;

while(fastfast-next)

slow=slow-next;

fast=fast-next-next;

returnslow;

}

4、鏈表中倒數第k個節點

鏈接直達:

鏈表中倒數第k個節點

題目:

思路:

快慢指針

定義兩個指針slow和fast,讓fast先走k步,再讓slow和fast同時走,當fast走到尾部時,slow就是倒數第k個,因為這樣的話slow和fast的差距始終是k個,當fast走到空時結束。此題同樣可以走k-1步,不過當fast走到尾部時結束,也就是fast的下一個節點指向空時結束,都一樣。先拿走k步舉例,如圖所示:

代碼如下:

structListNode*FindKthToTail(structListNode*pListHead,intk){

//writecodehere

structListNode*fast=pListHead;

structListNode*slow=pListHead;

while(k--)

//if判斷,防止k大于鏈表的長度

if(fast==NULL)

returnNULL;

fast=fast-next;

while(fast)

fast=fast-next;

slow=slow-next;

returnslow;

}

5、合并兩個有序鏈表

鏈接直達:

合并兩個有序鏈表

題目:

思路:

法一:歸并(取小的尾插)---帶頭節點

假設新鏈表的頭叫head并指向NULL,還需要定義一個指針tail來方便后續的找尾,依次比較list1和list2節點的值,把小的放到新鏈表head上,并更新tail,再把list1或list2更新一下。當list1和list2兩個鏈表中一個走到空時,直接把剩下的鏈表所有剩下的元素拷進去即可

代碼如下:

structListNode*mergeTwoLists(structListNode*list1,structListNode*list2){

//檢查list1或list2一開始就為NULL的情況

if(list1==NULL)

returnlist2;

if(list2==NULL)

returnlist1;

structListNode*head=NULL;

structListNode*tail=head;

while(list1list2)

if(list1-vallist2-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;

returnhead;

}

法二:哨兵位的頭節點

解釋下帶頭節點:

比如說同樣一個鏈表存1,2,3。不帶頭節點只有這三個節點,head指向1。而帶頭節點的同樣存3個值,不過有4個節點,head指向頭部這個節點,這個節點不存儲有效數據

帶頭結點有如下好處,不用判斷head和tail是否為空了,也不用判斷list1和list2是否為空了,會方便不少。和上述思路一樣,取小的下來尾插,直接鏈接到tail后面即可。但是要注意返回的時候要返回head的next,因為題目給的鏈表是不帶頭的,而head本身指向的就是那個頭,所以要返回下一個。

代碼如下:

structListNode*mergeTwoLists(structListNode*list1,structListNode*list2){

structListNode*head=NULL,*tail=NULL;

head=tail=(structListNode*)malloc(sizeof(structListNode));

head-next=NULL;

while(list1list2)

if(list1-vallist2-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;

structListNode*list=head-next;

free(head);

head=NULL

returnlist;

}

6、鏈表分割

鏈接直達:

鏈表分割

題目:

思路:

定義兩個鏈表lesshead和greaterhead。遍歷原鏈表,把x的插入到鏈表1,把x的插入到鏈表2,最后再把鏈表1和鏈表2鏈接起來。在定義兩個尾指針以跟進鏈表1和2新增元素

代碼如下:

classPartition{

public:

ListNode*partition(ListNode*pHead,intx){

//writecodehere

structListNode*lessHead,*lessTail,*greaterHead,*greaterTail;

lessHead=lessTail=(structListNode*)malloc(sizeof(structListNode));

greaterHead=greaterTail=(structListNode*)malloc(sizeof(structListNode));

lessTail-next=greaterTail-next=NULL;

structListNode*cur=pHead;

while(cur)

if(cur-valx)

lessTail-next=cur;

lessTail=lessTail-

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論