其实没有那么难,亏我还想了好几天,花费了我好长的时间,不过只要理解了链表头和指针变量的关系,基本就OK了。
我初学链表的时候就是搞不懂为什么要p1->next=p1->next->next,p1=p1->next,p1=head->next。等等之类的东西。其实p1->next就是一个空的数据域,程序要系统开辟的空间用来存储数据的,首先,p1,p2,head,等等之类定义的就是一个指针,next的作用相当于存储地址,比如p1=head->next,相当于把head后面的数据的头地址放到了p1中,然后就可以通过访问p1访问链表中的数据。然后就是p1=p1->next,
记住,链表建立之初除了表尾的next没有数据外,其他基本都有数据的地址存储着。好比如1,2,3,4,5,6。现在p1->data=3。此时p1->next中就存储着4的地址和连接5的地址的通道。p1->next->data=4,p1->next->next->data=5。不建议这样写,代码的可读性十分差。其他依次类推。只有基本理解了next的作用,链表的代码才能看的懂。另外建议多画图。
好了,关于链表的合并,没啥好说的,上代码。
#include <stdio.h>
#include <stdlib.h>
//#include "LinkList.h"
typedef int ElemType;
typedef struct LNode {
ElemType data; //数据域
struct LNode* next; //指针域
}LNode, * LinkList; // LinkList为指向结构体LNode的指针类型
//单链表的初始化,即:构造一个带头结点的空的单链表
void LL_Initiate(LinkList* L);
// 释放链表中各个结点
void LL_Free(LinkList* L);
// 判断链表是否为空。
bool LL_IsEmpty(LinkList L);
// 输入n个数据元素,采用头插法,创建一个带头结点的单链表L。
void LL_Create_H(LinkList* L, int n);
// 输入n个数据元素,采用尾插法,创建一个带头结点的单链表L。
void LL_Create_R(LinkList* L, int n);
// 输出整个链表。
void LL_Print(LinkList L);
//已知单链表LA和LB的元素按值非递减排列
//归并LA和LB得到新的单链表LC,LC的元素也按值非递减排列。
void MergeList_L(LinkList LA, LinkList LB, LinkList* LC);
void LL_Initiate(LinkList* L)
//单链表的初始化,即:构造一个带头结点的空的单链表
{
*L = (LNode*)malloc(sizeof(LNode));
(*L)->next = NULL;
}
void LL_Free(LinkList* L)
// 释放链表中各个结点。
{
LinkList p;
while (*L)
{
p = *L;
*L = (*L)->next;
free(p);
}
}
bool LL_IsEmpty(LinkList L)
// 判断链表是否为空。
{
return L->next == NULL;
}
void LL_Create_H(LinkList* L, int n)
// 输入n个数据元素,采用头插法,创建一个带头结点的单链表L。
{
LNode* s; int i;
*L = (LNode*)malloc(sizeof(LNode)); (*L)->next = NULL; //建立一个带头结点的空链表
for (i = 0; i < n; i++)
{
s = (LNode*)malloc(sizeof(LNode)); //生成新结点
scanf_s("%d", &s->data); //输入元素值
s->next = (*L)->next; (*L)->next = s; //插入到表头
}
}
void LL_Create_R(LinkList* L, int n)
// 输入n个数据元素,采用尾插法,创建一个带头结点的单链表L。
{
LNode* r, * s; int i;
*L = (LNode*)malloc(sizeof(LNode)); (*L)->next = NULL; //建立一个带头结点的空链表
r = *L; //尾指针r指向头结点
for (i = 0; i < n; i++)
{
s = (LNode*)malloc(sizeof(LNode)); //生成新结点
scanf_s("%d", &s->data); //输入元素值
s->next = NULL; r->next = s; //插入到表尾
r = s; //r指向新的尾结点
}
}
void LL_Print(LinkList L)
// 输出整个链表。
{
LNode* p;
p = L->next;
while (p)
{
printf("%d ", p->data); p = p->next;
}
printf("\n");
}
void MergeList_L(LinkList LA, LinkList LB, LinkList* LC)
//已知单链表LA和LB的元素按值非递减排列
//归并LA和LB得到新的单链表LC,LC的元素也按值非递减排列。
{
// 请在这里补充代码,完成本关任务
/********** Begin *********/
LNode* p1 = NULL;
LNode* p2 = NULL;//建立指向LA和LB和指针变量
LNode* head = NULL;//建立第三个链表的头指针。
//比较两个链表第一个的大小,确定第三条链表的首地址
if (LA->next->data < LB->next->data)
{
head = LA;
p1 = LA->next;
p2 = LB->next;
}
else
{
head = LB;
p1 = LA->next;
p2 = LB->next;
}
(*LC)= head;//赋值给LC
LNode* p3 = (*LC);
while (p1 != NULL && p2 != NULL)
{
if (p1->data <= p2->data)
{
p3->next = p1;
p3 = p1;
p1 = p1->next;
}
else
{
p3->next = p2;
p3 = p2;
p2 = p2->next;
}
}
if (p1 != NULL)
p3->next = p1;
if (p2 != NULL)
p3->next = p2;
/********** End **********/
}
int main()
{
LinkList A, B, C; int n;
scanf_s("%d", &n);//输入A表的元素个数
LL_Create_R(&A, n);
scanf_s("%d", &n);//输入B表的元素个数
LL_Create_R(&B, n);
MergeList_L(A, B, &C); //合并
LL_Print(C);
LL_Free(&C);
}