将两个单链表合并为一个单链表(C语言实现)
目的:掌握单链表的应用和算法设计
内容:L1 =(x1, x2, …, xn ),L2 =(y1, y2, …, ym ),他们是两个线性表,采用带头结点的单链表存储,设计一个算法合并L1、L2,结果放在线性表L3中。
要求:
L3 = (x1, y1, x2, y2, …, xm, ym, x(m+1), xn) m<=n
L3 = (x1, y1, x2, y2, …, xn, yn, y(n+1), ym) m>n
L3仍采用单链表存储,算法的空间复杂度为O(1)。
思路:由于空间复杂度为O(1),所以可在L1和L2的基础上创建L3,即直接将L1和L2交错链接在L3后面。
算法实现
bool DivideList(LinkNode* L1, LinkNode* L2, LinkNode*& L3) //L1、L2、L3为三个单链表的头结点
{
//如果L1和L2中均没有数据
if (L1->next == NULL && L2->next == NULL) {
return false;
}
//直到L3申请成功
while (!L3) {
L3 = (LinkNode*)malloc(sizeof(LNode));
}
LinkNode* p, * q, * r;
p = L1->next; //p为L1的工作指针
q = L2->next; //q为L2的工作指针
r = L3; //r为L3的尾指针
//当p和q均不为空时
while (p && q) {
r->next = p; //先接L1
r = r->next; //尾指针后移
p = p->next; //p指针后移
r->next = q; //再接L2
r = r->next; //尾指针后移
q = q->next; //q指针后移
r->next = NULL; //尾指针的next应该置空
}
//当p不为空时
if (p) {
r->next = p; //将剩余的接在尾指针后面
}
//当q不为空时
if (q) {
r->next = q; //将剩余的接在尾指针后面
}
return true;
}
bool DivideList(LinkNode* L1, LinkNode* L2, LinkNode*& L3)中用到了引用参数,引用参数在C++里才有,所以源代码文件格式应为”.cpp”。
与主函数相结合
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode* next;
}LinkNode;
bool DivideList(LinkNode* L1, LinkNode* L2, LinkNode*& L3); //L1、L2、L3为三个单链表的头结点
bool InitList(LinkNode*& L); //链表产生
bool DispList(LinkNode* L); //链表输出
int main(int argc, const char* argv[])
{
LinkNode* L1 = NULL, * L2 = NULL, * L3 = NULL;
int x;
bool flag = false;
InitList(L1);
InitList(L2);
flag = DivideList(L1, L2, L3);
if (flag)
printf("算法执行成功。\n");
else
printf("算法执行失败。\n");
DispList(L3);
return 0;
}
bool InitList(LinkNode*& L) //建立单链表
{
while (!L) {
L = (LinkNode*)malloc(sizeof(LNode));
}
L->next = NULL;
int i, n;
LinkNode* p = NULL, * q = NULL;
q = L;
printf("请输入数据规模:\n");
scanf("%d", &n);
printf("请输入数据:\n");
for (i = 0; i < n; i++) {
while (!p) {
p = (LinkNode*)malloc(sizeof(LNode));
}
scanf("%d", &p->data);
q->next = p;
q = p;
p = q->next = NULL;
}
return true;
}
bool DispList(LinkNode* L) //输出单链表
{
LinkNode* p = L->next;
while (p) {
printf("\t%d", p->data);
p = p->next;
}
printf("\n");
return true;
}
bool DivideList(LinkNode* L1, LinkNode* L2, LinkNode*& L3) //L1、L2、L3为三个单链表的头结点
{
//直到L3申请成功
while (!L3) {
L3 = (LinkNode*)malloc(sizeof(LNode));
}
LinkNode* p, * q, * r;
p = L1->next; //p为L1的工作指针
q = L2->next; //q为L2的工作指针
r = L3; //r为L3的尾指针
//当p和q均不为空时
while (p && q) {
r->next = p; //先接L1
r = r->next; //尾指针后移
p = p->next; //p指针后移
r->next = q; //再接L2
r = r->next; //尾指针后移
q = q->next; //q指针后移
r->next = NULL; //尾指针的next应该置空
}
//当p不为空时
if (p) {
r->next = p; //将剩余的接在尾指针后面
}
//当q不为空时
if (q) {
r->next = q; //将剩余的接在尾指针后面
}
return true;
}