Files
studycode/datastructure/2025301205+施光甲+实验一.cpp
2025-12-03 23:08:39 +08:00

254 lines
6.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}