算法题:合并两个有序的链表
来源:互联网 发布:恶意软件图片 编辑:程序博客网 时间:2024/06/05 23:47
说明:本文仅供学习交流,转载请标明出处,欢迎转载!
题目:已知有两个有序的单链表,其头指针分别为head1和head2,实现将这两个链表合并的函数:
Node* ListMerge(Node *head1,Node *head2)
这个算法很像我们排序算法中的归并排序,只能说“很像”,因为思想是一样的,但是这个与归并排序还是有区别的,区别如下:
1.归并排序是针对有序数组,而这里是有序链表;
2.归并排序排序的时间复杂度为o(nlogn),而这里的时间复杂度最坏情况下为O(m+n),最好的情况下为O(min{m,n})。
3.归并排序需要重新申请空间,而这里无需再重新申请空间,只需改变链表结点的指针指向。
而这里算法的思想跟归并排序是一样的,都是对两个待归并的线性表分别设置1个指针,比较这两个当前指针的大小,将小的结点加入到合并后的线性表中,并向后移动当前指针。若两个线性表中,至少有一个表扫描完,走将对应的另一个表之间整体添加到合并后的线性表中。在这里:链表和数组的区别在于,链表只需要改变当前合并序列尾指针的位置,而数组则要将剩下的值依次复制到归并表的尾部。
算法的递归实现如下:
Node *ListMerge1(Node *head1,Node *head2)//采用递归的方法实现{if(head1==NULL)return head2;if(head2==NULL)return head1;Node *head=NULL;if(head1->value < head2->value){head=head1;head->next=ListMerge1(head1->next,head2);}else{head=head2;head->next=ListMerge1(head1,head2->next);}return head;}
算法的非递归实现如下:
Node *ListMerge(Node *head1,Node *head2){if(!head1) return head2;if(!head2) return head1;Node *head=NULL;//合并后的头指针Node *p1=head1;//p1用于扫描链表1Node *p2=head2;//p2用于扫描链表2if(head1->value<head2->value){head=head1;p1=head1->next;}else{head=head2;p2=head2->next;}Node *p=head;//p永远指向最新合并的结点while(p1 && p2)//如果循环停止,则p1或p2至少有一个为NULL{if(p1->value<p2->value){p->next=p1;p1=p1->next;}else{p->next=p2;p2=p2->next;}p=p->next;}if(p1)//如果链1还没走完{p->next=p1;}else if(p2)//如果链2还没走完{p->next=p2;}return head;}
整个测试代码如下:
#include<iostream>using namespace std;struct Node{int value;Node* next;Node(int v):value(v){}};/*创建一个链表,1->2->3->4->5->6->7*/Node* CreateList1()//创建一个有序的单链表1{ Node *head; Node *n1=new Node(1); Node *n3=new Node(3); Node *n5=new Node(5); Node *n7=new Node(7); Node *n9=new Node(9); head=n1; n1->next=n3; n3->next=n5; n5->next=n7; n7->next=n9; n9->next=NULL; return head;}Node* CreateList2()//创建一个有序的单链表2{ Node *head; Node *n2=new Node(2); Node *n4=new Node(4); Node *n6=new Node(6); Node *n8=new Node(8); head=n2; n2->next=n4; n4->next=n6; n6->next=n8; n8->next=NULL; return head;}void FreeList(Node *head)//将链表空间释放{if(head==NULL){return ;}else{Node *temp=head->next;delete head;head=temp;FreeList(head);}}void VisitList(Node *head)//遍历链表中的元素,用递归的方法遍历{if(head){cout<<head->value<<"->";VisitList(head->next);}else{cout<<"null"<<endl;}}Node *ListMerge(Node *head1,Node *head2){if(!head1) return head2;if(!head2) return head1;Node *head=NULL;//合并后的头指针Node *p1=head1;//p1用于扫描链表1Node *p2=head2;//p2用于扫描链表2if(head1->value<head2->value){head=head1;p1=head1->next;}else{head=head2;p2=head2->next;}Node *p=head;//p永远指向最新合并的结点while(p1 && p2)//如果循环停止,则p1或p2至少有一个为NULL{if(p1->value<p2->value){p->next=p1;p1=p1->next;}else{p->next=p2;p2=p2->next;}p=p->next;}if(p1)//如果链1还没走完{p->next=p1;}else if(p2)//如果链2还没走完{p->next=p2;}return head;}Node *ListMerge1(Node *head1,Node *head2)//采用递归的方法实现{if(head1==NULL)return head2;if(head2==NULL)return head1;Node *head=NULL;if(head1->value < head2->value){head=head1;head->next=ListMerge1(head1->next,head2);}else{head=head2;head->next=ListMerge1(head1,head2->next);}return head;}int main(){Node *head1=CreateList1();Node *head2=CreateList2();cout<<"归并前"<<endl;cout<<"链表1:";VisitList(head1);cout<<"链表2:";VisitList(head2);cout<<"合并后的链表:";//Node *head=ListMerge(head1,head2);Node *head=ListMerge1(head1,head2);VisitList(head);FreeList(head);return 0;}
测试结果如下:
参考资料-------------《剑指offer》
0 0
- 合并两个有序链表的算法
- 算法:两个有序链表的合并
- 算法题:合并两个有序的链表
- 算法题:合并两个有序的链表
- 有序的合并两个有序链表
- 两个有序链表合并算法
- 算法学习----合并两个有序的链表
- 两个有序链表的合并问题
- 实现两个有序链表的合并
- 合并两个有序的链表
- 合并两个有序的链表
- 合并两个有序的链表
- 两个有序链表的合并
- 合并两个有序的链表
- 两个有序单向链表的合并
- 实现两个有序链表的合并
- 合并两个有序的链表
- 合并两个有序的链表
- vmware虚拟机上网问题
- Oracle简单查询语句
- 常见的HTTP返回码
- 七夕前面试被虐总结
- SQLserver 中 Text 数据类型 在 EntityFramework 中使用注意
- 算法题:合并两个有序的链表
- {}企业如何进行组合营销
- OC实例变量可见度 setter方法和getter方法
- 几种线程池的实现算法分析
- Android画图之Matrix(深入)
- 数据库schema、catalog
- poj 1163 The Triangle
- DTD学习笔记(一),来自于w3school
- Mac环境变量设置