合并链表
例2.3
有两个链表LA和LB,其元素均为非递减有序排列,编写算法,将它们合并成一个链表LC,要求LC也是非递减有序排列。
例如,LA=(2,2,3),LB=(1,3,3,4),则LC=(1,2,2,3,3,3,4)。
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct Node
{
int num;
struct Node *next;
} Node, *LinkList;
//使用指针的指针进行的初始化,l对应二级指针,*l对应一级指针
void InitLinkList(LinkList *l)
{
*l = (LinkList)malloc(sizeof(Node)); //建立头结点
(*l)->next = NULL; //建立空的单链表
}
// 头插法,用好头指针控制新节点
void CreateFromHead(LinkList l)
{
LinkList n;
int number;
int flag = 1;
while (flag)
{
scanf("%d", &number);
if (number != -1)
{
n = (LinkList)malloc(sizeof(Node));
n->num = number;
n->next = l->next;
l->next = n;
}
else
flag = 0;
}
}
// 尾插法,设置一个尾指针进行控制
void CreateFromTail(LinkList l)
{
LinkList n = l, s;
int number;
int flag = 1;
while (flag)
{
scanf("%d", &number);
if (number != -1)
{
s = (LinkList)malloc(sizeof(Node));
n->next = s;
n = s; //这里的n相当于尾指针,一直指向链表末尾
s->next = NULL;
s->num = number;
}
else
flag = 0;
}
}
int DeleteLinkList(LinkList l, int index)
{
int number;
LinkList temp = l, node;
for (int i = 0; i < index - 1; i++)
temp = temp->next;
node = temp;
temp = temp->next;
return number;
}
void PrintLinkList(LinkList l)
{
LinkList temp = l;
while (temp->next)
{
temp = temp->next;
printf("%d ", temp->num);
}
}
// void mergeList(LinkList LA, LinkList LB, LinkList LC)
// {
// LinkList s;
// LinkList n = LC;
// LA = LA->next;
// LB = LB->next;
// while (LA && LB)
// {
// s = (LinkList)malloc(sizeof(Node));
// if (LA->num < LB->num)
// {
// s->num = LA->num;
// LA = LA->next;
// }
// else
// {
// s->num = LB->num;
// LB = LB->next;
// }
// n->next = s;
// n = s;
// s->next = NULL;
// }
// while (LA)
// {
// s = (LinkList)malloc(sizeof(Node));
// s->num = LA->num;
// LA = LA->next;
// n->next = s;
// n = s;
// s->next = NULL;
// }
// while (LB)
// {
// s = (LinkList)malloc(sizeof(Node));
// s->num = LB->num;
// LB = LB->next;
// n->next = s;
// n = s;
// s->next = NULL;
// }
// }
void mergeList(LinkList LA, LinkList LB, LinkList LC)
{
LinkList pa = LA->next;
LinkList pb = LB->next;
LinkList pc = LC;
while (pa && pb)
{
LinkList s = (LinkList)malloc(sizeof(Node));
if (!s)
{
printf("内存分配失败\n");
exit(1);
}
if (pa->num < pb->num)
{
s->num = pa->num;
pa = pa->next;
}
else
{
s->num = pb->num;
pb = pb->next;
}
pc->next = s;
pc = s;
s->next = NULL;
}
// 处理剩余元素,哪个有剩余,直接剩余所有的连接上去
if (pa)
{
pc->next = pa;
}
else
{
pc->next = pb;
}
}
int main()
{
LinkList LA, LB, LC;
InitLinkList(&LA);
InitLinkList(&LB);
InitLinkList(&LC);
CreateFromTail(LA);
CreateFromTail(LB);
mergeList(LA, LB, LC);
PrintLinkList(LC);
return 0;
}
总结
这里对于合并函数mergeList的改进:
1.改用pa,pb,pc控制LA,LB,LC,防止原有链表头指针的改变。
2.对于剩余部分的处理,不需要使用循环,直接将剩余链表部分整个接上去即可。