两个有序单链表合并成第三个有序的单链表

其实没有那么难,亏我还想了好几天,花费了我好长的时间,不过只要理解了链表头和指针变量的关系,基本就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);
}
发布了20 篇原创文章 · 获赞 1 · 访问量 2495

猜你喜欢

转载自blog.csdn.net/m0_46198325/article/details/104925978
今日推荐