剑指Offer-17-合并有序链表
2015-11-13 22:06
323 查看
题目:
已知两个分别递增有序的单向链表,将两个有序链表合并为一个有序递增的单向链表。
思路:
(1)使用递归的方式
1.使用两个指针pa,pb分别指向两个有序的链表a,b的头结点。
2.如果pa为空返回pb,如果pb为空,返回pa。
3.如果pa,pb均不为空
如果pa->value <= pb->value,使指针head指向pa,并递归pa->next与pb;
4.如果pa->value > pb->value,使指针head指向pb,并递归pb->next与pa;
5.返回head.
(2)非递归方式
1.使用两个指针pa,pb分别指向两个有序的链表a,b的头结点,同时使prea指向pa所指结点的前一个结点;
2.移动两个指针,如果pa->value <= pb->value,将prea指向pa,pa指向下一个结点,pb不变。
3.否则,如果pa->value > pb->value,则指针t指向pb->next,prea指向pb,pb->next指向pa,pa指向pb,pb指向t。
已知两个分别递增有序的单向链表,将两个有序链表合并为一个有序递增的单向链表。
思路:
(1)使用递归的方式
1.使用两个指针pa,pb分别指向两个有序的链表a,b的头结点。
2.如果pa为空返回pb,如果pb为空,返回pa。
3.如果pa,pb均不为空
如果pa->value <= pb->value,使指针head指向pa,并递归pa->next与pb;
4.如果pa->value > pb->value,使指针head指向pb,并递归pb->next与pa;
5.返回head.
(2)非递归方式
1.使用两个指针pa,pb分别指向两个有序的链表a,b的头结点,同时使prea指向pa所指结点的前一个结点;
2.移动两个指针,如果pa->value <= pb->value,将prea指向pa,pa指向下一个结点,pb不变。
3.否则,如果pa->value > pb->value,则指针t指向pb->next,prea指向pb,pb->next指向pa,pa指向pb,pb指向t。
#include <iostream> using namespace std; struct ListNode { int value; ListNode *pNext; }; //递归方式实现有序链表的合并 ListNode* merge(ListNode *pa,ListNode *pb) { //pa所指链表为空 if(pa == NULL) return pb; //pb所指链表为空 if(pb == NULL) return pa; //pa,pb均不为空 ListNode *head = NULL; //pa所指链表的头结点值小于pb所指链表的头结点值 if(pa->value < pb->value){ //头指针指向pa,继续递归 head = pa; head->pNext = merge(pa->pNext,pb); } else { //头指针指向pb,继续递归 head = pb; head->pNext = merge(pb->pNext,pa); } return head; } //非递归方式实现有序链表的合并 ListNode* mergeSortedList(ListNode *pHeada,ListNode *pHeadb) { if(pHeada == NULL) return pHeadb; if(pHeadb == NULL) return pHeada; //pa指向a链表的头结点 //pb指向b链表的头结点 //pPre初始为NULL ListNode *pa = pHeada; ListNode *pb = pHeadb; ListNode *pPrea = NULL; //循环比较链表中的各值 while(pa && pb) { //pa指向的值小于等于pb指向的值 if(pa->value<=pb->value) { //prea指向pa,pa后移 pPrea= pa; pa = pa->pNext; } //pa指向的值大于pb指向的值 else { //使用临时指针指向pb所指结点的下一个结点 ListNode *t = pb->pNext; if(pPrea != NULL) { //如果pPrea不为空,这时pPrea->next应指向pb //否则pPrea->next不需指向pb。 pPrea->pNext = pb; } pb->pNext = pa; pPrea = pb; pb = t; } } if(pa == NULL){ pPrea->pNext = pb; return pHeada; } return pHeadb; } /** * 向链表中插入结点 */ void insertList(ListNode **pHead,ListNode *value) { ListNode *head = *pHead; if(head == NULL) { *pHead = value; } else { while(head->pNext != NULL) { head = head->pNext; } head->pNext = value; } } /** * 向链表中插入结点 */ void insertList(ListNode **pHead,int value) { ListNode *p = new ListNode(); p->value = value; p->pNext = NULL; insertList(pHead,p); } /** * 打印链表 */ void print(ListNode *p) { while(p) { cout<<p->value<<" "; p = p->pNext; } cout<<endl; } void testRecusiveMerge() { //测试实例 //1.a 1,2,3 b 4,5,6 ListNode *a = NULL; insertList(&a,1); insertList(&a,2); insertList(&a,3); ListNode *b = NULL; insertList(&b,4); insertList(&b,5); insertList(&b,6); a = merge(a,b); print(a); //2.c 4,5,6 b 1,2,3 ListNode *c = NULL; insertList(&c,4); insertList(&c,5); insertList(&c,6); ListNode *d = NULL; insertList(&d,1); insertList(&d,2); insertList(&d,3); c = merge(c,d); print(c); //3.e 1,3,5 f 2,4,6 ListNode *e = NULL; insertList(&e,1); insertList(&e,3); insertList(&e,5); ListNode *f = NULL; insertList(&f,2); insertList(&f,4); insertList(&f,6); e = merge(e,f); print(e); } void testNormalMerge() { //测试实例 //1.a 1,2,3 b 4,5,6 ListNode *a = NULL; insertList(&a,1); insertList(&a,2); insertList(&a,3); ListNode *b = NULL; insertList(&b,4); insertList(&b,5); insertList(&b,6); a = mergeSortedList(a,b); print(a); //2.c 4,5,6 b 1,2,3 ListNode *c = NULL; insertList(&c,4); insertList(&c,5); insertList(&c,6); ListNode *d = NULL; insertList(&d,1); insertList(&d,2); insertList(&d,3); c = mergeSortedList(c,d); print(c); //3.e 1,3,5 f 2,4,6 ListNode *e = NULL; insertList(&e,1); insertList(&e,3); insertList(&e,5); ListNode *f = NULL; insertList(&f,2); insertList(&f,4); insertList(&f,6); e = mergeSortedList(e,f); print(e); } int main() { testRecusiveMerge(); cout<<"------------------"<<endl; testNormalMerge(); return 0; }
相关文章推荐
- [C/C++]反转链表
- 关于指针的一些事情
- C#实现基于链表的内存记事本实例
- 有关数据库SQL递归查询在不同数据库中的实现方法
- C#中的递归APS和CPS模式详解
- WinForm实现按名称递归查找控件的方法
- 使用SqlServer CTE递归查询处理树、图和层次结构
- C#中的尾递归与Continuation详解
- C# Pointer指针应用实例简述
- C++智能指针实例详解
- C++指向函数的指针实例解析
- 关于c语言指针的两处小tip分享
- 浅析iterator与指针的区别
- 探讨C++中数组名与指针的用法比较分析
- 详解C++中的指针、数组指针与函数指针
- C语言实现带头结点的链表的创建、查找、插入、删除操作
- C++中字符串以及数组和指针的互相使用讲解
- C语言安全之数组长度与指针实例解析
- C++中指向对象的常指针与指向常对象的指针详解
- 指向变量的常指针与指向常变量的指针详细解析