课程代码

This commit is contained in:
zpooi
2025-12-03 23:08:39 +08:00
commit 290f629d2c
63 changed files with 7065 additions and 0 deletions

View File

@@ -0,0 +1,253 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct LNode
{
int data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList; // LinkList为指向LNode类型的指针类型
// 初始化四个链表L、M、N、H
void chushihua(LinkList &L, LinkList &M, LinkList &N, LinkList &H)
{
//todo list 1: 为四个链表分配头节点并初始化
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
M = (LinkList)malloc(sizeof(LNode));
M->next = NULL;
N = (LinkList)malloc(sizeof(LNode));
N->next = NULL;
H = (LinkList)malloc(sizeof(LNode));
H->next = NULL;
printf("链表初始化成功!\n");
}
// 判断链表L是否为空表
void Emp(LinkList &L)
{
if (L->next == NULL) //todo list 2: 判断头节点的next是否为空
printf("链表为空表。\n");
else
printf("链表为非空表。\n");
}
// 求表长返回L中数据元素个数
void Length(LinkList L){
LNode *p; //申请临时变量p
p = L->next; //p指向第一个结点(首元结点)
int length = 0;
//todo list 3: 遍历单链表,统计结点数
while (p != NULL) {
length++;
p = p->next;
}
printf("链表长度为:%d\n", length);
}
// 1、建立递增有序链表向链表L中插入n个整数插入时保持链表的有序性从小到大
void charu_1(LinkList &L, int n)
{
LNode *q,*p;
int i; // 循环变量声明
for (i = 1; i <= n; i++)
{
p = L; //在每次循环开始时将p指向链表的头节点L
q = (LinkList)malloc(sizeof(LNode)); //为新的节点分配内存并将q指向这块内存
printf("请输入第%d个整数的值", i);
scanf("%d", &q->data); //将输入的值存储在q指向的节点的data字段中
q->next = NULL; //将新节点的next指针设置为NULL表示新节点当前不指向任何节点。
if (p->next == NULL) //如果p的下一个节点是NULL即链表为空或p指向链表的最后一个节点
//todo list 4: 直接插入新节点
L->next = q;
else //如果链表不为空或p不是指向链表的最后一个节点则进入这个else块查找新节点的插入位置
{
while (p->next != NULL && p->next->data < q->data)
{
//todo list 5: p指针不断往后移动
p = p->next;
if (p->next == NULL)
break;
}
//todo list 6: 插入*q结点
q->next = p->next;
p->next = q;
}
}
printf("数据插入完成!\n");
}
// 显示链表L的所有元素
void xianshi(LinkList &L)
{
LNode *p; //申请临时变量p //LinkList p;
p = L;
while (p->next != NULL)
{
printf("%4d", p->next->data);
p = p->next;
}
printf("\n");
}
// 2、分解将链表L中的元素分为奇数和偶数两个链表M和N并分别显示它们。
void fenbiao(LinkList &L, LinkList &M, LinkList &N)
{
LNode *j,*o,*p;
p = L->next; //todo list 7: p指针指向第一个数据节点
// 初始化M和N链表
M->next = NULL;
N->next = NULL;
LNode *m_tail = M; // M链表的尾指针
LNode *n_tail = N; // N链表的尾指针
while (p != NULL)
{
if (p->data % 2 == 0) //找出偶数元素,用尾插法将这些偶数元素建立成一个【偶数链表】
{
o = (LinkList)malloc(sizeof(LNode));
//todo list 8: 使用尾插法插入偶数节点
o->data = p->data;
o->next = NULL;
n_tail->next = o;
n_tail = o;
}
else //找出奇数元素,用尾插法将这些奇数元素建立成一个【奇数链表】
{
j = (LinkList)malloc(sizeof(LNode));
//todo list 9: 使用尾插法插入奇数节点
j->data = p->data;
j->next = NULL;
m_tail->next = j;
m_tail = j;
}
//todo list 10: p指针往后移动
p = p->next;
}
printf("奇数链表为:");
xianshi(M);
printf("偶数链表为:");
xianshi(N);
}
// 3、合并一个递减链表将奇数链表J和偶数链表O合并为一个新的链表H合并时保持元素的有序性。
void hebiao(LinkList &J, LinkList &O, LinkList &H)
{
// 先将两个链表转换为数组,然后排序,最后用头插法创建递减链表
int data[100]; // 假设最多100个元素
int count = 0;
LNode *p;
int i, j; // 循环变量声明
LNode *t;
// 收集奇数链表的数据
p = J->next;
while (p != NULL) {
data[count++] = p->data;
p = p->next;
}
// 收集偶数链表的数据
p = O->next;
while (p != NULL) {
data[count++] = p->data;
p = p->next;
}
// 对数据进行升序排序(从小到大)- 这样头插后会变成降序
for (i = 0; i < count - 1; i++) {
for (j = i + 1; j < count; j++) {
if (data[i] > data[j]) { // 如果前一个元素大于后一个元素,交换它们
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
// 使用头插法创建递减链表
H->next = NULL;
for (i = 0; i < count; i++) {
t = (LinkList)malloc(sizeof(LNode));
t->data = data[i];
t->next = H->next;
H->next = t;
}
printf("合并后的递减链表为:");
xianshi(H); //显示合表H
}
int main()
{
//生成新结点作为头结点,用头指针分别指向各头结点
LinkList head = (LinkList)malloc(sizeof(LNode));
LinkList ji = (LinkList)malloc(sizeof(LNode));
LinkList ou = (LinkList)malloc(sizeof(LNode));
LinkList he = (LinkList)malloc(sizeof(LNode));
// 初始化链表
head->next = NULL;
ji->next = NULL;
ou->next = NULL;
he->next = NULL;
int choose = -1, n;
printf("*********************************************\n");
printf("********** 实验一 *******\n");
printf("********** 单链表操作 *******\n");
printf("*********************************************\n");
printf("********** 1.初始化单链表 *******\n");
printf("********** 2.建立递增链表 *******\n");
printf("********** 3.分成奇/偶两链表 *******\n");
printf("********** 4.合并成递减单链表 *******\n");
printf("********** 5.显示建立的(递增)单链表整体 *******\n");
printf("********** 6.求单链表长度 *******\n");
printf("********** 7.判断链表是否为空 *******\n");
printf("********** 0.退出程序 *******\n");
printf("*********************************************\n");
while (choose)
{
printf("请输入您的选择:");
scanf("%d", &choose);
switch (choose)
{
case 1:
chushihua(head, ji, ou, he);
break;
case 2:
printf("请输入要插入的整数个数:");
scanf("%d", &n);
charu_1(head, n);
break;
case 3:
fenbiao(head, ji, ou);
break;
case 4:
hebiao(ji, ou, he);
break;
case 5:
printf("当前(递增)单链表内容为:");
xianshi(head);
break;
case 6:
Length(head);
break;
case 7:
Emp(head);
break;
case 0:
printf("程序已退出,感谢使用!\n");
exit(0);
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
}
return 0;
}