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;
}