欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++合并兩個(gè)升序鏈表的方式

 更新時(shí)間:2022年07月20日 09:30:38   作者:小源同學(xué)r  
這篇文章主要介紹了C/C++合并兩個(gè)升序鏈表的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

合并兩個(gè)升序鏈表

算法的思想

1.需要合并的兩個(gè)鏈表La,Lb,合并之后的鏈表Lc(用La的頭節(jié)點(diǎn))。

2.定義兩個(gè)輔助指針Pa,Pb分別是鏈表La,Lb的復(fù)制指針。

3.從首元節(jié)點(diǎn)開始比較,當(dāng)兩個(gè)鏈表都沒有到達(dá)鏈表尾部的時(shí)候,依次取其中較小的數(shù)據(jù)進(jìn)行鏈接到Lc的最后

4.如果兩個(gè)元素的值相同,取La鏈的,把Lb鏈表的元素刪除(確保新鏈表沒有重復(fù)的元素)

5.當(dāng)一個(gè)鏈表結(jié)束的時(shí)候,把非空鏈表剩余的所有元素鏈接在Lc表的最后

6.釋放Lb的頭節(jié)點(diǎn)(Lb鏈表就被刪除了)

代碼實(shí)現(xiàn)+注釋

void MergeList(LinkList &La, LinkList &Lb, LinkList &Lc)
{
	LinkList pa, pb, pc;
	pa = La->next;
	pb = Lb->next;
	Lc = pc = La;
	while (pa && pb)
	{
		if (pa->data < pb->data)
		{ //把小的數(shù)據(jù)(pa)鏈接到Lc表上
			pc->next = pa;
			pc = pa;	   //保證指向最后的節(jié)點(diǎn)上
			pa = pa->next; //指針后移
		}
		else if (pa->data > pb->data)
		{ //把小的數(shù)據(jù)(pb)鏈接到Lc表上
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
		else
		{ //如果兩個(gè)元素的值相同,取La鏈的,把Lb鏈表的元素刪
			pc->next = pa;
			pc = pa;
			pa = pa->next;
			LNode *p = pb->next; //保存pb下一個(gè)節(jié)點(diǎn)
			delete (pb);
			pb = p;
		}
	}
	pc->next = pa?pa:pb;
	delete(Lb);
}

合并K個(gè)升序鏈表(遞歸方法)

這個(gè)題的思路和歸并排序的思路一樣。

歸并的思想

遞歸地,或迭代地,將兩個(gè)已經(jīng)有序的數(shù)組或鏈表合并成一個(gè)有序的大數(shù)組或大鏈表。

先來看合并兩個(gè)有序鏈表的代碼

傳入兩個(gè)鏈表的頭結(jié)點(diǎn),new一個(gè)head節(jié)點(diǎn)當(dāng)作合并后的鏈表的頭結(jié)點(diǎn),當(dāng)兩個(gè)鏈表都沒有走到鏈尾的時(shí)候,將兩鏈表的節(jié)點(diǎn)有序放入合并后的鏈表中。

當(dāng)某一個(gè)鏈表已經(jīng)走到了鏈尾,此時(shí)把另一個(gè)鏈表剩下的部分接到合并后的鏈表尾部。

返回head節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),因?yàn)閔ead節(jié)點(diǎn)是new出來的,要記得delete釋放掉這個(gè)節(jié)點(diǎn)的內(nèi)存。

ListNode* mergeTwo(ListNode* l1,ListNode*l2){
?? ??? ?// new一個(gè)節(jié)點(diǎn)當(dāng)作合并后的鏈表的頭結(jié)點(diǎn)
? ? ? ? ListNode* head=new ListNode(0);
? ? ? ? ListNode* temp=head;
? ? ? ? // 當(dāng)兩個(gè)鏈表都沒有走到鏈尾的時(shí)候,將兩鏈表的節(jié)點(diǎn)有序放入合并后的鏈表中
? ? ? ? while(l1 && l2){
? ? ? ? ? ? if(l1->val <= l2->val){
? ? ? ? ? ? ? ? temp->next=l1;
? ? ? ? ? ? ? ? temp=temp->next;
? ? ? ? ? ? ? ? l1=l1->next;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? temp->next=l2;
? ? ? ? ? ? ? ? temp=temp->next;
? ? ? ? ? ? ? ? l2=l2->next;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 當(dāng)某一個(gè)鏈表已經(jīng)走到了鏈尾,此時(shí)把另一個(gè)鏈表剩下的部分接到合并后的鏈表尾部。
? ? ? ? if(l1){
? ? ? ? ? ? temp->next=l1;
? ? ? ? }else{
? ? ? ? ? ? temp->next=l2;
? ? ? ? }
? ? ? ? temp=head->next;
? ? ? ? delete head;
? ? ? ? head=nullptr;
? ? ? ? return temp;
? ? }

我們?cè)賮砜春喜個(gè)鏈表的遞歸方法

數(shù)組lists內(nèi)存放了K個(gè)鏈表首節(jié)點(diǎn),我們將數(shù)組先分成兩部分,再將每部分又分為兩部分,直到分成了一個(gè)鏈表首節(jié)點(diǎn)為一部分,遞歸程序就走到底了,然后開始調(diào)用合并兩個(gè)有序鏈表的函數(shù),將鏈表兩兩合并,此時(shí)遞歸程序不斷地返回上一級(jí),直到將所有鏈表合并成一個(gè)鏈表。

class Solution {
public:
?? ?// 傳入存放了K個(gè)鏈表首節(jié)點(diǎn)的數(shù)組lists
? ? ListNode* mergeKLists(vector<ListNode*>& lists) {
? ? ? ? if(lists.empty()){
? ? ? ? ? ? return nullptr;
? ? ? ? }
? ? ? ? return mergeAll(lists,0,lists.size()-1);
? ? }
?? ?// 遞歸地對(duì)鏈表進(jìn)行兩兩合并
? ? ListNode* mergeAll(vector<ListNode*>& lists,int begin,int end){
? ? ? ? ListNode* l1=nullptr;
? ? ? ? ListNode* l2=nullptr;
? ? ? ? ListNode* res=nullptr;
? ? ? ? if(begin<end){
? ? ? ? ? ? int mid=(begin+end)/2;
? ? ? ? ? ? l1=mergeAll(lists,begin,mid);
? ? ? ? ? ? l2=mergeAll(lists,mid+1,end);
? ? ? ? ? ? res=mergeTwo(l1,l2);
? ? ? ? }else{
? ? ? ? ? ? return lists[begin];
? ? ? ? }
? ? ? ? return res;
? ? }
?? ?// 合并兩個(gè)有序鏈表的函數(shù)
? ? ListNode* mergeTwo(ListNode* l1,ListNode*l2){
? ? ? ? ListNode* head=new ListNode(0);
? ? ? ? ListNode* temp=head;
? ? ? ? while(l1 && l2){
? ? ? ? ? ? if(l1->val <= l2->val){
? ? ? ? ? ? ? ? temp->next=l1;
? ? ? ? ? ? ? ? temp=temp->next;
? ? ? ? ? ? ? ? l1=l1->next;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? temp->next=l2;
? ? ? ? ? ? ? ? temp=temp->next;
? ? ? ? ? ? ? ? l2=l2->next;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if(l1){
? ? ? ? ? ? temp->next=l1;
? ? ? ? }else{
? ? ? ? ? ? temp->next=l2;
? ? ? ? }
? ? ? ? temp=head->next;
? ? ? ? delete head;
? ? ? ? head=nullptr;
? ? ? ? return temp;
? ? }
};

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++?STL容器詳解之紅黑樹部分模擬實(shí)現(xiàn)

    C++?STL容器詳解之紅黑樹部分模擬實(shí)現(xiàn)

    本文主要對(duì)紅黑樹進(jìn)行了詳細(xì)介紹,并對(duì)其核心功能進(jìn)行了模擬實(shí)現(xiàn)。文中的代碼對(duì)我們的學(xué)習(xí)或工作有一定的價(jià)值,感興趣的小伙伴可以了解一下
    2021-12-12
  • 基于C語言實(shí)現(xiàn)靜態(tài)通訊錄的示例代碼

    基于C語言實(shí)現(xiàn)靜態(tài)通訊錄的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的靜態(tài)通訊錄,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下
    2022-07-07
  • C語言算法練習(xí)之折半查找的實(shí)現(xiàn)

    C語言算法練習(xí)之折半查找的實(shí)現(xiàn)

    二分查找法(也叫折半查找)其本質(zhì)是分治算法的一種。這篇文章主要介紹了如何利用C語言實(shí)現(xiàn)折半查找,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-05-05
  • QT5實(shí)現(xiàn)電子時(shí)鐘

    QT5實(shí)現(xiàn)電子時(shí)鐘

    這篇文章主要為大家詳細(xì)介紹了QT5實(shí)現(xiàn)電子時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 詳解安卓系統(tǒng)中的Android.mk文件

    詳解安卓系統(tǒng)中的Android.mk文件

    這篇文章主要介紹了詳解安卓系統(tǒng)中的Android.mk文件,該文件用來告訴系統(tǒng)關(guān)于源代碼的編譯,需要的朋友可以參考下
    2015-07-07
  • Qt利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的示例代碼

    Qt利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Qt如何利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的 功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-02-02
  • Qt網(wǎng)絡(luò)編程實(shí)現(xiàn)TCP通信

    Qt網(wǎng)絡(luò)編程實(shí)現(xiàn)TCP通信

    這篇文章主要為大家詳細(xì)介紹了Qt網(wǎng)絡(luò)編程實(shí)現(xiàn)TCP通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++設(shè)計(jì)模式之代理模式(Proxy)

    C++設(shè)計(jì)模式之代理模式(Proxy)

    這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之代理模式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • C++中的strcmp函數(shù)

    C++中的strcmp函數(shù)

    strcmp函數(shù)是C++標(biāo)準(zhǔn)庫中用于字符串比較的重要函數(shù),在C++中,字符串比較是一項(xiàng)常見的操作,用于判斷兩個(gè)字符串是否相等或者大小關(guān)系,本文介紹C++中的strcmp函數(shù),感興趣的朋友一起看看吧
    2024-03-03
  • C語言實(shí)現(xiàn)文本文件/二進(jìn)制文件格式互換

    C語言實(shí)現(xiàn)文本文件/二進(jìn)制文件格式互換

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)文本文件和二進(jìn)制文件格式互換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03

最新評(píng)論