合并链表
例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.对于剩余部分的处理,不需要使用循环,直接将剩余链表部分整个接上去即可。
分类:
数据结构与算法 / 链表
, 数据结构与算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了