C语言实现单链表

 IDE:Visual Studio 2022

#define _CRT_SECURE_NO_WARNINGS // 定义宏,避免使用scanf()时的警告
#include<stdio.h> 
#include<stdlib.h> 
typedef struct LNode { // 定义单链表的结构体
	int data; // 数据域
	struct LNode* next; // next指针,指向下一个节点
} LNode, * LinkList; // 定义结构体别名 LNode 和指针类型 LinkList
// 函数声明
void creatlist(LinkList& L, int n); // 创建单链表
void deletelist(LinkList& L, int i); // 单链表的删除
void insertlist(LinkList& L, int x, int i); // 单链表的插入
void printlist(LinkList& L); // 显示单链表
void addlist(LinkList& L); // 合并单链表
// 创建单链表的函数实现
void creatlist(LinkList& L, int n) {
	LinkList p, q; // 定义两个指针变量 p 和 q
	L = (LinkList)malloc(sizeof(LNode)); // 动态分配内存给头节点
	L->next = NULL; // 头节点的 next 指针初始化为 NULL
	p = L; // p 指向头节点
	int i; // 循环变量
	for (i = 0; i < n; i++) { // 循环 n 次,创建 n 个节点
		q = (LinkList)malloc(sizeof(LNode)); // 动态分配内存给新节点
		printf("data %d:", i + 1); // 提示用户输入数据
		scanf("%d", &q->data); // 用户输入数据
		q->next = p->next; // 新节点的 next 指向 p 的下一个节点
		p->next = q; // p 的 next 指向新节点
		p = q; // p 移动到新节点
	}
}
// 插入节点的函数实现
void insertlist(LinkList& L, int x, int i) {
	int j = 0; // 计数器,用于确定插入位置
	LinkList p, s; // 定义两个指针变量 p 和 s
	p = L; // p 指向头节点
	while (p != NULL && j < i - 1) { // 寻找第 i-1 个节点
		p = p->next;
		j++;
	}
	if (p == NULL || j > i - 1) { // 如果 p 为空或者 j 超过 i-1,说明位置不正确
		printf("ERROR");
		exit(0); // 退出程序
	}
	s = (LinkList)malloc(sizeof(LNode)); // 动态分配内存给新节点 s
	s->data = x; // 设置新节点的数据
	s->next = p->next; // 新节点的 next 指向 p 的下一个节点
	p->next = s; // p 的 next 指向新节点
	printlist(L); // 打印链表
}
// 删除节点的函数实现
void deletelist(LinkList& L, int i) {
	LinkList p; // 定义指针变量 p
	p = L; // p 指向头节点
	int j = 0; // 计数器,用于确定删除位置
	while (p != NULL && j < i - 1) { // 寻找第 i-1 个节点
		p = p->next;
		j++;
	}
	if (p == NULL && j > i - 1) { // 如果 p 为空或者 j 超过 i-1,说明位置不正确
		exit(0); // 退出程序
	}
	p->next = p->next->next; // 删除节点,将 p 的 next 指向要删除节点的下一个节点
	printlist(L); // 打印链表
}
// 查找节点的函数实现
void findlist(LinkList& L, int i) {
	int j = 0; // 计数器,用于确定查找位置
	LinkList p; // 定义指针变量 p
	p = L; // p 指向头节点
	while (p != NULL && j < i - 1) { // 寻找第 i-1 个节点
		p = p->next;
		j++;
	}
	printf("%d\n", p->next->data); // 输出查找位置的节点数据
}
// 打印链表的函数实现
void printlist(LinkList& L) {
	LinkList p; // 定义指针变量 p
	p = L->next; // p 指向第一个节点
	while (p != NULL) { // 遍历链表
		printf("%3d", p->data); // 打印节点数据
		p = p->next; // p 移动到下一个节点
	}
	printf("\n"); // 换行
}
// 合并两个单链表的函数实现
void addlist(LinkList& L) {
	int n; // 另一个链表的长度
	LinkList L0, L1, p, p0, p1; // 定义指针变量
	printf("另一个单链表的长度:");
	scanf("%d", &n); // 用户输入另一个链表的长度
	creatlist(L0, n); // 创建另一个链表
	p = L->next; // p 指向第一个链表的第一个节点
	p0 = L0->next; // p0 指向另一个链表的第一个节点
	L1 = L; // L1 指向第一个链表的头节点
	p1 = L1; // p1 指向第一个链表的第一个节点
	while (p && p0) { // 当两个链表都不为空时
		if (p->data < p0->data) { // 比较两个节点的数据
			p1->next = p; // 将较小的节点接到结果链表
			p1 = p; // p1 移动到下一个节点
			p = p->next; // p 移动到下一个节点
		}
		else {
			p1->next = p0; // 将较大的节点接到结果链表
			p1 = p0; // p1 移动到另一个链表的下一个节点
			p0 = p0->next; // p0 移动到另一个链表的下一个节点
		}
	}
	p1->next = p ? p : p0; // 将剩余的链表接到结果链表
	p1 = L1->next; // p1 指向结果链表的第一个节点
	while (p1) { // 遍历结果链表
		printf("%d  ", p1->data); // 打印节点数据
		p1 = p1->next; // p1 移动到下一个节点
	}
	printf("\n"); // 换行
}
int main() { // 主函数
	LinkList L; // 定义链表指针 L
	int n, o, x, i, f; // 定义变量
	printf("单链表的长度:");
	scanf("%d", &n); // 用户输入链表长度
	creatlist(L, n); // 创建链表
	printf("0.结束使用\n");
	printf("1.单链表的插入\n");
	printf("2.单链表的删除\n");
	printf("3.单链表的查找\n");
	printf("4.显示单链表\n");
	printf("5.合并单链表\n");
	while (1) { // 无限循环,直到用户选择结束
		printf("输入你要实现的功能:\n");
		scanf("%d", &o); // 用户选择功能
		if (o == 0) { break; } // 如果用户选择结束,则退出循环
		else {
			switch (o) { // 根据用户选择的功能执行对应的操作
			case 1:
				printf("插入的数据:");
				scanf("%d", &x); // 用户输入要插入的数据
				printf("插入的位置:");
				scanf("%d", &i); // 用户输入插入位置
				insertlist(L, x, i); // 调用插入函数
				break;

			case 2:
				printf("删除的位置:");
				scanf("%d", &i); // 用户输入要删除的位置
				deletelist(L, i); // 调用删除函数
				break;

			case 3:
				printf("查找的位置:");
				scanf("%d", &i); // 用户输入要查找的位置
				findlist(L, i); // 调用查找函数
				break;

			case 4:
				printlist(L); // 调用打印函数
				break;
			case 5:
				addlist(L);//调用合并函数
				break;

			default:printf("Error!");
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值