题目:两个递增的有序单链表la和lb,编程把la和lb合并成新的递增的有序单链表lc;
分析:无论你解决什么问题,记住一句话,一定要省题,有时在解决问题时,没有省题,最后怎么也解决不出来,后来才发现题目都没有看清楚。
所以省题也是十分重要。
光是文字,我们都不是很喜欢,所以我找了一些图片帮助你们去理解。
我之前在想两个有序链表合并时,我就想到集合的并集,以至于我在合并链表把相同的节点删除了就剩下一个。但是我发现这个想法是错误的,这里的合并是包含所有元素 。
这个题目的思路:首先,我们要把两个链表表示出来,那么我们接下来的问题就如何将两个链表合并?这里用到了一个方法:因为这是递增序列,每个链表的第一个元素,都是这个链表的最小元素,那么两个链表第一个元素比较,就可以得到最小元素。将最小的元素拿出来,再次进行相同操作。
具体代码:
#include <stdio.h>
typedef struct Node
{
int data;
struct Node *next;
}LinkNode,*LinkList;
void CreateLinkList(LinkList * L);
void HeBingLinkList(LinkList * L,LinkList * LA,LinkList * LB);
void PrintfLinkList(LinkList L);
int main(void)
{
LinkList LA,LB,L;
CreateLinkList(&LA);
CreateLinkList(&LB);
HeBingLinkList(&L,&LA,&LB);
PrintfLinkList(L);
}
void CreateLinkList(LinkList * L) //创建单链表函数
{
LinkList r,p;
int a; //辅助变量
*L=(LinkNode*)malloc(sizeof(LinkNode));
(*L)->next=NULL; //建立头节点
r=*L;
scanf("%d",&a);
while(a!=-1)
{
p=(LinkNode*)malloc(sizeof(LinkNode));
p->data=a;
p->next=r->next;
r->next=p;
r=p;
scanf("%d",&a);
}
}
void HeBingLinkList(LinkList * L,LinkList * LA,LinkList * LB) //合并单链表
{
LinkList PA=*LA,PB=*LB;
*L=(LinkNode*)malloc(sizeof(LinkNode));
LinkList P=*L;
LinkList P1,P2;
if(PA->next==NULL&&PB->next==NULL)
{
printf("NULL"); //判断两个链表是否为空
exit(0);
}
PA=PA->next;
PB=PB->next;
if((PA==NULL&&PB!=NULL)||(PA!=NULL&&PB==NULL))
{
if(PA==NULL)
{
P->next=PB;
}
if(PB==NULL)
{
P->next=PA;
}
}
else
{
while(PA!=NULL&&PB!=NULL)
{
if(PA->data>=PB->data)
{
P->next=PB;
P=PB;
PB=PB->next;
}
else
{
P->next=PA;
P=PA;
PA=PA->next;
}
}
if(PA==NULL)
{
P->next=PB;
}
else
{
P->next=PA;
}
}
}
void PrintfLinkList(LinkList L)
{
LinkList P=L;
P=P->next;
while(P)
{
printf("%d",P->data);
if(P->next!=NULL)
{
printf(" ");
}
P=P->next;
}
}
在合并单链表的函数中:循环的标志是我之前想了PA->next!=NULL&&PB->next!=NULL,发现不对,举个例子,第一个链表1,3,5
第二个链表2,4,6,8,10;你就发现不对;