網站首頁 編程語言 正文
合并兩個升序鏈表
算法的思想
1.需要合并的兩個鏈表La,Lb,合并之后的鏈表Lc(用La的頭節(jié)點)。
2.定義兩個輔助指針Pa,Pb分別是鏈表La,Lb的復制指針。
3.從首元節(jié)點開始比較,當兩個鏈表都沒有到達鏈表尾部的時候,依次取其中較小的數(shù)據(jù)進行鏈接到Lc的最后
4.如果兩個元素的值相同,取La鏈的,把Lb鏈表的元素刪除(確保新鏈表沒有重復的元素)
5.當一個鏈表結束的時候,把非空鏈表剩余的所有元素鏈接在Lc表的最后
6.釋放Lb的頭節(jié)點(Lb鏈表就被刪除了)
代碼實現(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é)點上
pa = pa->next; //指針后移
}
else if (pa->data > pb->data)
{ //把小的數(shù)據(jù)(pb)鏈接到Lc表上
pc->next = pb;
pc = pb;
pb = pb->next;
}
else
{ //如果兩個元素的值相同,取La鏈的,把Lb鏈表的元素刪
pc->next = pa;
pc = pa;
pa = pa->next;
LNode *p = pb->next; //保存pb下一個節(jié)點
delete (pb);
pb = p;
}
}
pc->next = pa?pa:pb;
delete(Lb);
}
合并K個升序鏈表(遞歸方法)
這個題的思路和歸并排序的思路一樣。
歸并的思想
遞歸地,或迭代地,將兩個已經有序的數(shù)組或鏈表合并成一個有序的大數(shù)組或大鏈表。
先來看合并兩個有序鏈表的代碼
傳入兩個鏈表的頭結點,new一個head節(jié)點當作合并后的鏈表的頭結點,當兩個鏈表都沒有走到鏈尾的時候,將兩鏈表的節(jié)點有序放入合并后的鏈表中。
當某一個鏈表已經走到了鏈尾,此時把另一個鏈表剩下的部分接到合并后的鏈表尾部。
返回head節(jié)點的下一個節(jié)點,因為head節(jié)點是new出來的,要記得delete釋放掉這個節(jié)點的內存。
ListNode* mergeTwo(ListNode* l1,ListNode*l2){
?? ??? ?// new一個節(jié)點當作合并后的鏈表的頭結點
? ? ? ? ListNode* head=new ListNode(0);
? ? ? ? ListNode* temp=head;
? ? ? ? // 當兩個鏈表都沒有走到鏈尾的時候,將兩鏈表的節(jié)點有序放入合并后的鏈表中
? ? ? ? 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;
? ? }
我們再來看合并K個鏈表的遞歸方法
數(shù)組lists內存放了K個鏈表首節(jié)點,我們將數(shù)組先分成兩部分,再將每部分又分為兩部分,直到分成了一個鏈表首節(jié)點為一部分,遞歸程序就走到底了,然后開始調用合并兩個有序鏈表的函數(shù),將鏈表兩兩合并,此時遞歸程序不斷地返回上一級,直到將所有鏈表合并成一個鏈表。
class Solution {
public:
?? ?// 傳入存放了K個鏈表首節(jié)點的數(shù)組lists
? ? ListNode* mergeKLists(vector<ListNode*>& lists) {
? ? ? ? if(lists.empty()){
? ? ? ? ? ? return nullptr;
? ? ? ? }
? ? ? ? return mergeAll(lists,0,lists.size()-1);
? ? }
?? ?// 遞歸地對鏈表進行兩兩合并
? ? 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;
? ? }
?? ?// 合并兩個有序鏈表的函數(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;
? ? }
};
原文鏈接:https://blog.csdn.net/qq_43216714/article/details/123648122
相關推薦
- 2022-05-10 使用node讀取文件和寫入文件
- 2022-07-31 pandas中提取DataFrame某些列的一些方法_python
- 2022-04-15 Python爬蟲之requests庫基本介紹_python
- 2022-07-09 python實現(xiàn)通訊錄系統(tǒng)_python
- 2022-03-29 詳解C++?的STL迭代器原理和實現(xiàn)_C 語言
- 2023-01-05 Flutter?Widget之NavigationBar使用詳解_Android
- 2022-04-21 Android自定義View實現(xiàn)標簽流效果_Android
- 2022-04-27 Jquery實現(xiàn)移動端控制DIV拖拽_jquery
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支