ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

(C语言)数据结构-线性表之单链表操作(交集,并集,差集,排序,拼接,去重)

2021-11-27 21:58:00  阅读:219  来源: 互联网

标签:head 单链 线性表 并集 差集 next LinkList data 节点


1.头文件和数据类型的定义

#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;

2.定义单链表的结构体

//定义单链表的结构体 
typedef struct Node{
	ElemType data;		//数据域 存储该Node数据 
	struct Node *next;	//指针域 指向下一个Node 
}LinkList;

3.初始化单链表

//返回一个初始化的节点L 
LinkList* InitList(){
	LinkList* L;								//定义一个节点 
	L = (LinkList*)malloc(sizeof(LinkList));	//分配节点空间 
	L->next = NULL;								//节点指针域置空 
	return L;
}

4.在单链表尾部添加元素

//功能说明:在单链表的尾部添加元素,返回添加元素后的尾节点 
//参数1:LinkList *r 要添加元素的单链表的尾节点
//参数2:ElemType e 要添加的元素e 
//返回值:LinkList * r  新的尾节点 
//实现方式:
//1.定义一个临时的节点n  给临时节点开辟空间 
//2.元素e存入临时节点的数据域中 将临时节点n的next置空 
//3.将尾节点的next指向临时节点n 尾节点后移 返回新的尾节点 
LinkList *tailAddElemLinkList(LinkList *r,ElemType e) {
	//定义一个临时的节点n  给临时节点开辟空间 
	LinkList *n = (LinkList*)malloc(sizeof(LinkList));
	//元素e存入节点n中 
	n->data = e;
	//将临时节点n的next置空 
	n->next = NULL;
	//将新节点插入末尾 
	r->next = n;
	//尾指针后移一位 
	r = r->next;
	//返回新的尾节点 
	return r;
}

5.创建单链表

//功能说明:创建单链表,从键盘输入len个数插入到单链表L中 
//参数1: LinkList* L 要链接节点的头节点
//参数2:int len 要添加的节点个数
//实现方式:
//定义一个尾指针r 定义变量e用于存储每次输入的元素值
//使用循环每次输入一个元素值 将元素通过尾部添加到单链表 
void createList(LinkList* L,int len){
	//定义一个尾指针r并初始化为头指针 
	LinkList* r = L;
	//定义变量e用于存储每次输入的元素值 
	ElemType e;
	printf("请输入%d个单链表的元素:",len);
	int i;
	for(i = 0; i < len; i++){
		//获取输入的元素 
		scanf("%d",&e);
		r = tailAddElemLinkList(r,e);
	} 
}

6.输出单链表中的元素值

//功能说明:输出单链表中的节点值 
//参数: LinkList* L 要显示的单链表的头节点 
//实现方式:定义一个节点p指向第一个节点 循环判断节点p是否存在,存在则输出data,节点p向后移动一位 
void showLinkList(LinkList* L) {
	LinkList* p = L->next;
	while(p){
		printf("%d ",p->data);
		p = p->next; 
	}
}

7.单链表排序

//功能说明:单链表从小到大的排序 冒泡排序 (值交换)
//参数: LinkList* L 单链表的头节点 
// 实现方式: 从第一个元素节点开始逐一比较,将节点的值进行交换
void linkListSort(LinkList* L){
	LinkList* i = L->next;
	LinkList* j = L->next;
	//外层循环 
	while(i){
		//内层循环 
		while(j){
			//值交换 
			if(i->data > j->data){
				ElemType e = i->data;
				i->data = j->data;
				j->data = e;
			}
			j = j->next;
		}
		j = i->next;
		i = i->next;
	}
}

8.判断某个元素在单链表中是否存在

//功能说明:判断某个元素在单链表中是否存在 存在返回1 不存在返回-1 
//参数1: LinkList *L 单链表的头节点
//参数2:要查找的元素e
//实现方式:遍历单链表L,拿元素e和单链表L中的所有元素匹配 成功返回1 失败返回-1 
int searchElem(LinkList *L, ElemType e){
	LinkList *temp = L->next;
	while(temp){
		if(e == temp->data) return 1;
		temp = temp->next;
	}
	return -1;
}

9.单链表数据去重拼接

//功能说明:将单链表的数据存到另一个单链表的末尾 重复元素不存入 
//参数1: LinkList *L1 存取元素的单链表的头节点
//参数2: LinkList *L1_rear 存取元素的单链表的尾节点
//参数3:LinkList *L2_head 被存取的单链表的头节点
//实现方式:
// 遍历单链表L2,判断每一个元素在L1中是否存在
//不存在则存入该元素到L1,L1的尾节点后移,最后返回L1的尾节点 
LinkList *spliceLinkList(LinkList *L1,LinkList *L1_rear,LinkList *L2_head){
	LinkList *r = L1_rear;
	while(L2_head){
		//判断单链表a里面的元素在单链表L存不存在, 不存在则存入(数据去重) 
		if(searchElem(L1,L2_head->data) == -1){
			//将L2_head->data从尾节点r存入L1中 
			r = tailAddElemLinkList(r,L2_head->data);
		}
		L2_head = L2_head->next; 
	}
	return r;
} 

10.返回两个单链表的并集

//功能说明:返回两个单链表的并集 
//参数1:LinkList *a 单链表a的头节点
//参数1:LinkList *b 单链表b的头节点
//实现方式: 将两个单链表去重后存入一起,排序成一个有序链表 (使用上面封装的函数实现) 
LinkList *unionLinkList(LinkList *a,LinkList *b){
	//初始化一个单链表L用于存储 单链表a和单链表b的并集 
	LinkList *L = InitList();
	LinkList *r = L;
	LinkList *a_head = a->next;
	LinkList *b_head = b->next;
	r = spliceLinkList(L,r,a_head);
	r = spliceLinkList(L,r,b_head);
	//排序合并的并集结果 
	linkListSort(L);  
	return L; 
} 

11.返回单链表a-b的差集

//功能说明:返回单链表a-b的差集 
//参数1:LinkList *a 单链表a的头节点
//参数1:LinkList *b 单链表b的头节点
//实现方式: 
//遍历单链表b
//判断单链表b里面的每一个元素在单链表a中是否存在 
//不存在则存入新的单链表L 
LinkList *diffLinkList(LinkList *a,LinkList *b){
	//初始化一个单链表L用于存储 单链表a和单链表b的并集 
	LinkList *L = InitList();
	LinkList *r = L;
	LinkList *a_head = a->next;
	while(a_head){
		//判断单链表a里面的元素在单链表b存不存在,不存在则存入(数据去重) 
		if(searchElem(b,a_head->data) == -1 && searchElem(L,a_head->data) == -1){
			r = tailAddElemLinkList(r,a_head->data);
		}
		a_head = a_head->next; 
	}
	//排序合并的并集结果 
	linkListSort(L);
	return L; 
}

12.返回两个单链表的交集

//功能说明:返回单链表a和b的交集 (和上面的函数一模一样,判断里面改一下就行)
//参数1:LinkList *a 单链表a的头节点
//参数1:LinkList *b 单链表b的头节点
//实现方式: 
//遍历单链表b
//判断单链表b里面的每一个元素在单链表a中是否存在 
//存在则存入新的单链表L 
LinkList *intersectionLinkList(LinkList *a,LinkList *b) {
	//初始化一个单链表L用于存储 单链表a和单链表b的并集 
	LinkList *L = InitList();
	LinkList *r = L;
	LinkList *a_head = a->next;
	while(a_head){
		//判断单链表a里面的元素在单链表b存不存在, 不存在则存入(数据去重) 
		if(searchElem(b,a_head->data) == 1 && searchElem(L,a_head->data) == -1){
			r = tailAddElemLinkList(r,a_head->data);
		}
		a_head = a_head->next; 
	}
	//排序合并的并集结果 
	linkListSort(L);
	return L;
}

13.判断两个单链表是否相等

//功能说明:判断两个单链表是否完全相等
//参数1:LinkList *a 单链表a的头节点
//参数1:LinkList *b 单链表b的头节点
//返回值:相等返回 int 1 不相等返回 int 0
//单链表a和单链表b如果他们的差集都为空,则他们完全相等
int equalLinkList(LinkList *a,LinkList *b){
	//判断a-b和b-a的差集是否都为空  差集为空则相等 
	if(!diffLinkList(a,b)->next && !diffLinkList(b,a)->next){
		return 1;
	}
	return 0;
} 

14.main函数实现

int main(){
	//初始化一个节点作为头节点 
	LinkList* L1 = InitList();
	LinkList* L2 = InitList();
	int len;
	printf("请输入要创建的第一个单链表长度:"); 
	scanf("%d",&len);
	createList(L1,len);
	printf("第一个单链表的元素为:"); 
	showLinkList(L1);
	
	printf("\n请输入要创建的第二个单链表长度:"); 
	scanf("%d",&len);
	createList(L2,len);
	printf("第二个单链表的元素为:"); 
	showLinkList(L2);
	
	printf("\n两个单链表的并集:");
	showLinkList(unionLinkList(L1,L2));
	printf("\n单链表a-b的差集:");
	showLinkList(diffLinkList(L1,L2));
	printf("\n单链表b-a的差集:");
	showLinkList(diffLinkList(L2,L1));
	printf("\n单链表a和单链表b的交集:"); 
	showLinkList(intersectionLinkList(L2,L1));
	printf("\n单链表的数据是否相等:"); 
	if(equalLinkList(L2,L1)) 
		printf("相等");
	else 
		printf("不相等");
	return 0;
} 

样例输出1(两个相等的单链表):
在这里插入图片描述
样例输出2(两个不相等的单链表):
在这里插入图片描述

标签:head,单链,线性表,并集,差集,next,LinkList,data,节点
来源: https://blog.csdn.net/liulinet/article/details/121583251

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有