题目描述
有两个有序递增链表pa和pb,现在要把他们合并成一个链表,分别用递归算法和非递归算法实现
题目分析
非递归实现:
使用两个指针head 和p ,head 作为头结点,p作为活动指针.
如果pa所指元素<pb所指元素,那么把pa所指元素,放入合并后的链表中,然后把p->next指向pa,把p指向pa,把pb向后移动,即pb=pb->next
如果pa所指元素>pb所指元素,那么把pb所指元素,放入合并后的链表中,然后把p->next指向pb,把p指向pb,把pb向后移动,即pb=pb->next
如此往复,直到pa 或者pb 为 null 为止
核心方法如下:
//非递归实现两个链表合并
linklist mergelist(lnode * pa,lnode*pb)
{
int e,n;
linklist pc,head;
head=pc=(linklist)malloc(sizeof(lnode));
pc->next=NULL;
while(pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
//pc->next=pa?pa:pb;
pa==NULL ? pc->next=pb:pc->next=pa;
return head;
}
递归实现
递归终止条件:若head1为空,返回head2指针(head);若head2为空,返回head1指针(head)
递归过程:
(1)若pa->data < pb->data; head 指针应该指向pa所指向的节点,而且head->next应该指向pa->next和pb两个链表的合成序列的头指针;
(2)否则head 指针应该指向pb所指向的节点,而且head->next应该指向pb和pb->next两个链表的合成序列的头指针;
核心代码如下:
/*递归的合并两个有序链表*/
lnode * mergeLinkedList(lnode * head1,lnode * head2)
{
lnode *p=NULL;
if(head1==NULL&&head2==NULL)
return p;
else if(head1==NULL)
return head2;
else if(head2==NULL)
return head1;
else
{
if(head1->data < head2->data)
{
p = head1;
p->next = mergeLinkedList(head1->next,head2);
}
else
{
p = head2;
p->next = mergeLinkedList(head1,head2->next);
}
return p;
}
}
完整代码
#include <stdio.h>
#include <malloc.h>
typedef struct lnode {
int data;
struct lnode *next;
}lnode,*linklist;
linklist creatlist(int m)//创建链表
{
linklist p,l,s;
int i;
p=l=(linklist)malloc(sizeof(lnode));
p->next=NULL;
printf("请输入链表中的一个数字:");
scanf("%d",&p->data);
for(i=2;i<=m;i++)
{
s=(linklist)malloc(sizeof(lnode));
s->next = NULL;
printf("请输入第%d个数字",i);
scanf("%d",&s->data);
p->next=s;
p=p->next;
}
printf("/n");
return l;
}
void print(linklist h,int type)//打印链表
{
if(type==1){
linklist p=h->next;
}else{
linklist p=h;
}
int t=1;
printf("打印各个数字:\n");
do
{
printf("请输出第%d个数:",t);
printf("%d\n",p->data);
p=p->next;
t++;
}while(p);
}
//非递归实现两个链表合并
linklist mergelist(lnode * pa,lnode*pb)
{
int e,n;
linklist pc,head;
head=pc=(linklist)malloc(sizeof(lnode));
pc->next=NULL;
while(pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
//pc->next=pa?pa:pb;
pa==NULL ? pc->next=pb:pc->next=pa;
return head;
}
/*递归的合并两个有序链表*/
lnode * mergeLinkedList(lnode * head1,lnode * head2)
{
lnode *p=NULL;
if(head1==NULL&&head2==NULL)
return p;
else if(head1==NULL)
return head2;
else if(head2==NULL)
return head1;
else
{
if(head1->data < head2->data)
{
p = head1;
p->next = mergeLinkedList(head1->next,head2);
}
else
{
p = head2;
p->next = mergeLinkedList(head1,head2->next);
}
return p;
}
}
int main()
{
linklist head;
int e,n;
lnode *pa,*pb;
printf("请输入第一个链表的长度:");
scanf("%d",&e);
pa=creatlist(e);
printf("请输入第二个链表的长度:");
scanf("%d",&n);
pb=creatlist(n);
//递归和非递归方法请分别执行
//非递归写法
head=mergelist(pa,pb);
print(head,1);
printf("-----非递归算法结束----\n");
//递归写法
// head=mergeLinkedList(pa,pb);
// print(head,2);
// printf("----递归算法结束----\n");
return 0;
}