合并k个增序链表
来源:互联网 发布:windows如何快捷锁屏 编辑:程序博客网 时间:2024/04/29 22:27
合并k个增序链表
问题
归并排序是一个比较简单的算法,特别是二路归并排序,且用数组存储各个数列时。修改索引只需要简单的++操作即可。
但是如果换成链表,将二路换成多路,对链表操作接触不多的还是值得注意练习下的。
算法
多个链表的归并操作,其实容易混淆的就是指针的指向问题。A链表中某节点指向B中某节点,指完之后容易弄混,或者破坏了原有链表的关系而未保存导致遗漏。
只要把每次比较过后指针指向的修改操作统一起来,问题就很简单了。
此处用2个指针来保存头节点head,前一节点prev,用一个指针的指针min来修改索引完成++操作。当然,这种用法也相当于是限于c++类有指针的语言哈。没有指针的或者可以用引用来替代指针。
算法步骤:
1、遍历所有头节点找到最小的一个头节点。用min指向该头节点的地址。
2、如果是第一个节点,min指向的节点赋值给head与prev。修改min指向的头节点,令其指向其后一个节点。
3、如果不是第一个节点,令prev的后继指向min指向的节点。更新prev指向当前节点。++操作。
代码
代码如下:
/** * @brief MergeLists::mergSome * @param heads 要合并链表的头结点 * @return */MergeLists::Node *MergeLists::mergSome(std::vector<MergeLists::Node *> heads){ Node* head=NULL; ///<头节点,返回的指针 Node** min=NULL; ///<指向最小节点的指针的指针,用于修改索引 Node* prev=NULL; ///<新链表中前一节点。因为要将前一节点后继修改指向当前节点,所以保存 std::vector<MergeLists::Node *>::iterator iter; while(!heads.empty()){ min=NULL; for(iter=heads.begin();iter!=heads.end();iter++){ if((*iter)==NULL) continue; if(min==NULL) min=&(*iter); if((*min)->val>(*iter)->val) min=&(*iter); } //说明所有链表都遍历到了最后节点 if(min==NULL) break; //头节点指针,只赋值一次 if(head==NULL){ head=*min; //头节点赋值 prev=head; //更新前一节点指针 *min=(*min)->next; //让当前节点的链表头指向当前节点的下一节点。++操作 }else{ prev->next=*min; //前一节点的后继指向当前节点 prev=*min; //更新前一节点值 *min=(*min)->next; //++操作。 } } for(Node* p=head;p;p=p->next) std::cout<<p<<" "<<p->val<<std::endl;}
生成链表代码如下:
MergeLists::Node *MergeLists::makeList(std::vector<int> v){ Node* head=NULL; Node* cur=NULL; Node* prev=NULL; std::vector<int>::iterator iter; for(iter=v.begin();iter!=v.end();iter++){ cur=new Node(*iter); if(head==NULL) head=cur; if(prev!=NULL) prev->next=cur; prev=cur; } return head;}
头文件:
class MergeLists{public: MergeLists(){}; virtual ~MergeLists(){}; class Node{ public: Node(){}; Node(int v):val(v),next(NULL){}; int val; Node* next; }; Node* mergTwo(Node* f,Node* s); Node* mergSome(std::vector<Node*> heads); Node* makeList(std::vector<int> v);};
测试
测试代码如下:
MergeLists merge; MergeLists::Node* first=merge.makeList(std::vector<int>({1,2,4,6})); MergeLists::Node* sec=merge.makeList(std::vector<int>({3,5,7,9})); MergeLists::Node* third=merge.makeList(std::vector<int>({3,8,9,12,13})); merge.mergSome(std::vector<MergeLists::Node*>({first,sec,third}));
不支持vector列表初始化的拷贝赋值下吧。:)
测试结果:
0x14080160 10x14068428 20x1406ef70 30x14012a00 30x14057508 40x14074700 50x1406eed0 60x1405a370 70x1406dc20 80x14068560 90x14018180 90x1404f7f8 120x14077570 13
0 0
- 合并k个增序链表
- 合并k个有序数组
- 合并K个有序数组
- 合并K个有序数组
- 合并k个有序链表 Merge k Sorted Lists
- K链表合并 Merge k Sorted Lists
- Leetcode Merge k Sorted Lists 合并k个链表
- LeetCode 23. Merge k Sorted Lists(K路合并)
- 23. Merge k Sorted Lists 合并k个链表
- Merge k Sorted Lists(合并k个有序链)
- 基于堆的K路合并问题
- LeetCode 合并k个有序链表
- 题目:合并k个排序链表
- 合并k个排序链表
- 合并k个排序链表
- 合并k个有序链表
- 合并k个排序链表
- 合并k个排序链表,lintcode
- 关于云游戏实时编码流化资料
- javaWeb工作原理
- 对mongodb 的 WiredTiger Storage Engine 的理解
- JSTL : javaserverpages standard tag library JSP标准标签库
- POJ 1759 Garland 已翻译
- 合并k个增序链表
- Jmeter+jenkins的配置
- 如何做Linux内核的开发
- PAT A1028
- 视觉基础:关于机器视觉、机器学习及人工智能领域
- Unity3D——百度地图SDK接入(经验)
- ubuntu
- poj_1026 Cipher(置换群)
- PAT A1029