C 演算法之 合併兩個有序鍊錶

2021-07-01 19:40:43 字數 3769 閱讀 8610

題目:合併兩個已經排序好的鍊錶

方法1:

兩個鍊錶 

比如鍊錶1: 1->3->5->7->9

鍊錶2:  2->4->6->8->10

跟我們合併兩個陣列一樣,鍊錶1的頭結點  和鍊錶2的頭節點比較,如果鍊錶1頭節點的值大於鍊錶2頭接點的值,

那麼鍊錶2的頭結點為合併鍊錶的頭結點,那麼鍊錶1的頭節點繼續和鍊錶2的第二個節點(剩餘鍊錶2的頭結點)

作比較,但乙個鍊錶遍歷完之後,如果另外乙個鍊錶還沒有遍歷完,因為鍊錶本來就是排序的,所以讓合併鍊錶的

尾巴節點指向未遍歷完鍊錶的頭結點就可以

舉個例子:

鍊錶1: 1,3,5,23,34;

鍊錶2: 2,4,6,8,10;

當遍歷之後 鍊錶3:1,2,3,4,8,10  此時鍊錶2已經遍歷完,while迴圈退出,但是剩餘鍊錶1還有 23,34

此時 讓鍊錶3的尾巴節點10 鏈結 剩餘鍊錶的頭節點 23  就可以了

// 合併鍊錶.cpp : 定義控制台應用程式的入口點。  

//  

#include "stdafx.h"  

#include

using namespace std;  

struct listnode  

};  

/* 兩個鍊錶  比如鍊錶1: 1->3->5->7->9 

鍊錶2:  2->4->6->8->10 

跟我們合併兩個陣列一樣,鍊錶1的頭結點  和鍊錶2的頭節點比較,如果鍊錶1頭節點的值大於鍊錶2頭接點的值, 

那麼鍊錶2的頭結點為合併鍊錶的頭結點,那麼鍊錶1的頭節點繼續和鍊錶2的第二個節點(剩餘鍊錶2的頭結點) 

作比較,但乙個鍊錶遍歷完之後,如果另外乙個鍊錶還沒有遍歷完,因為鍊錶本來就是排序的,所以讓合併鍊錶的 

尾巴節點指向未遍歷完鍊錶的頭結點就可以 

舉個例子: 

鍊錶1: 1,3,5,23,34; 

鍊錶2: 2,4,6,8,10; 

當遍歷之後 鍊錶3:1,2,3,4,8,10  此時鍊錶2已經遍歷完,while迴圈退出,但是剩餘鍊錶1還有 23,34 

此時 讓鍊錶3的尾巴節點10 鏈結 剩餘鍊錶的頭節點 23  就可以了 

*/  

listnode* mergelist2(listnode* head1,listnode* head2)  

else if(head2 == null)  

listnode* mergehead = null;  

if (head1->m_data < head2->m_data)  

else  

listnode* tmpnode = mergehead;  

while (head1&&head2)  

else  

mergehead = mergehead->m_pnext;  

}  if (head1)  

if (head2)  

return tmpnode;  

}  int _tmain(int argc, _tchar* argv)  

listnode* phead2 = new listnode(2);  

pcur = phead2;  

for (int j = 4; j < 10; j+=2)  

listnode* head = mergelist2(phead1,phead2);  

while (head)  

getchar();  

return 0;  

}方法2:/*

我們分析兩個鍊錶的過程,首先從合併兩個鍊錶的頭結點開始,鍊錶1的頭節點的值小於鍊錶2的頭結點的值,因此鍊錶1的頭結點

就是合併鍊錶的頭節點,繼續合併剩下的鍊錶,在兩個鍊錶中剩餘的節點仍然是排序的,因此合併兩個鍊錶的步驟是一樣的,我們還是比較兩個頭結點的

值,此時鍊錶2的頭結點的值小於鍊錶1的頭結點的值,因此鍊錶2的頭結點是合併剩餘鍊錶的頭結點,我們把這個節點和前面合併鍊錶時得到的鍊錶的尾巴節點

鏈結起來

按照上面的分析可知:每次合併的步驟都是一樣的,由此我們想到了遞迴。 */

// 合併鍊錶.cpp : 定義控制台應用程式的入口點。  

//  

#include "stdafx.h"  

#include

using namespace std;  

struct listnode  

};  

/* 我們分析兩個鍊錶的過程,首先從合併兩個鍊錶的頭結點開始,鍊錶1的頭節點的值小於鍊錶2的頭結點的值,因此鍊錶1的頭結點 

就是合併鍊錶的頭節點,繼續合併剩下的鍊錶,在兩個鍊錶中剩餘的節點仍然是排序的,因此合併兩個鍊錶的步驟是一樣的,我們還是比較兩個頭結點的 

值,此時鍊錶2的頭結點的值小於鍊錶1的頭結點的值,因此鍊錶2的頭結點是合併剩餘鍊錶的頭結點,我們把這個節點和前面合併鍊錶時得到的鍊錶的尾巴節點 

鏈結起來 

按照上面的分析可知:每次合併的步驟都是一樣的,由此我們想到了遞迴。 

*/  

listnode* mergelist(listnode* phead1,listnode* phead2)  

else if (phead2 == null)  

listnode* pmergehead = null;  

if (phead1->m_data < phead2->m_data)  

else  

return pmergehead;  

}  int _tmain(int argc, _tchar* argv)  

listnode* phead2 = new listnode(2);  

pcur = phead2;  

for (int j = 4; j < 10; j+=2)  

listnode* head = mergelist2(phead1,phead2);  

while (head)  

getchar();  

return 0;  

}  看了這道題目,那麼上次的合併陣列也可以用遞迴這裡附上**:

// mergearray.cpp : 定義控制台應用程式的入口點。  

//  

#include "stdafx.h"  

#include

using namespace std;  

//遞迴方法  

void mergearray2(int a,int acount,int b,int blen)  

return;  

}  if (a[acount] > b[blen])  

else  

}  void mergearray(int a, int acount, int b, int blen)//acount為a陣列實際(狹義)長度,blen為b陣列實際長度  

else  

}  while(blen >= 0)  

}  int _tmain(int argc, _tchar* argv)  

;  int b = ;  

mergearray2(a,5,b,5);  

for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++)  

{  cout<

個人感覺合併陣列用遞迴不太好,因為考慮如果乙個陣列遍歷完另乙個陣列還沒有遍歷完這個情況有點麻煩,而如果是鍊錶的話,乙個數煉表歷完,

那麼這個鍊錶為空,則返回另外乙個鍊錶就可以了,也就是前面合併好的鍊錶自動鏈結上另外沒有遍歷完的鍊錶的那部分!

演算法 合併兩個有序鍊錶

有兩種方法,迭代和遞迴。迭代 不帶頭結點 node merge node head1 node head2 else 當前排序好的鍊錶的末尾節點 node pcurrent head while p1 null p2 null else 還有一方沒有遍歷完的情況 if p1 null pcurren...

演算法 合併兩個有序鍊錶

1.迭代,新建乙個哨兵節點,通過它的next指標指向串聯起兩個鍊錶 比較 l1 和 l2哪乙個比較小,讓哨兵節點的next指向比較小的節點 哨兵節點 l1 l2依次後推,直到又乙個鍊錶為空 如果 l1 為空,則哨兵節點指向l2 注意返回值為哨兵節點的next,因為哨兵節點的第乙個值是隨意給的 cla...

合併兩個有序鍊錶 C

合併兩個有序鍊錶 遞迴實現 演算法思想 遞迴終止條件 若head1為空,返回head2指標 head 若head2為空,返回head1指標 head 遞迴過程 1 若head1 data head2 data head 指標應該指向head2所指向的節點,而且head next應該指向head1和h...