课程代码
This commit is contained in:
253
datastructure/2025301205+施光甲+实验一.cpp
Normal file
253
datastructure/2025301205+施光甲+实验一.cpp
Normal 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;
|
||||
}
|
||||
136
datastructure/2025301205+施光甲+实验三.cpp
Normal file
136
datastructure/2025301205+施光甲+实验三.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAXSIZE 10
|
||||
typedef struct Queue
|
||||
{
|
||||
int *data; //存储空间的基地址
|
||||
int front, rear; //头指针、尾指针
|
||||
int count; //新增一个 count变量,用于记录队中元素个数
|
||||
}Queue;
|
||||
|
||||
//初始化队列
|
||||
void Init(Queue &Q)
|
||||
{
|
||||
Q.data = new int[MAXSIZE];
|
||||
//处理front, rear指针,以及count变量
|
||||
Q.front = 0;
|
||||
Q.rear = 0;
|
||||
Q.count = 0;
|
||||
}
|
||||
|
||||
//入队
|
||||
void EnQueue(Queue &Q, int e)
|
||||
{
|
||||
if (Q.count == MAXSIZE) //利用count判断队是否满
|
||||
printf("队满\n");
|
||||
else {
|
||||
//入队元素,尾指针+1
|
||||
Q.data[Q.rear] = e;
|
||||
Q.rear = (Q.rear + 1) % MAXSIZE; //循环队列,需要取模
|
||||
//更新count值
|
||||
Q.count++;
|
||||
printf("元素%d入队成功\n", e);
|
||||
}
|
||||
}
|
||||
|
||||
//出队
|
||||
void DelQueue(Queue &Q, int &e)
|
||||
{
|
||||
if (Q.count == 0) //利用count判断队是否空
|
||||
printf("队空\n");
|
||||
else{
|
||||
//出队元素,头指针+1
|
||||
e = Q.data[Q.front];
|
||||
Q.front = (Q.front + 1) % MAXSIZE; //循环队列,需要取模
|
||||
//更新count值
|
||||
Q.count--;
|
||||
printf("出队元素为:%d\n", e);
|
||||
}
|
||||
}
|
||||
|
||||
//判断队空
|
||||
void IsNull(Queue Q)
|
||||
{
|
||||
if (Q.count == 0) //利用count判断队是否空
|
||||
printf("队空\n");
|
||||
else
|
||||
printf("队不空\n");
|
||||
}
|
||||
|
||||
//显示整个队列
|
||||
void Display(Queue Q)
|
||||
{
|
||||
if (Q.count == 0) {
|
||||
printf("队列为空\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int tempFront = Q.front; // 使用临时变量,避免修改原队列
|
||||
int tempCount = Q.count; // 使用临时计数
|
||||
|
||||
while (tempCount > 0)
|
||||
{
|
||||
printf("%3d,", Q.data[tempFront]);
|
||||
tempFront = (tempFront + 1) % MAXSIZE; // 临时指针后移
|
||||
tempCount--; // 临时计数减1
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Queue Q;
|
||||
printf("------------------------------------\n");
|
||||
printf("1.初始化队列\n");
|
||||
printf("2.判断队列是否为空\n");
|
||||
printf("3.入队\n");
|
||||
printf("4.出队\n");
|
||||
printf("5.显示整个队列\n");
|
||||
printf("6.退出\n");
|
||||
printf("------------------------------------\n");
|
||||
int sel;
|
||||
while (1)
|
||||
{
|
||||
printf("请输入选项:");
|
||||
scanf("%d", &sel);
|
||||
switch (sel)
|
||||
{
|
||||
case 1:
|
||||
Init(Q);
|
||||
printf("队列已经初始化。\n");
|
||||
break;
|
||||
case 2:
|
||||
IsNull(Q);
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
int n, e;
|
||||
printf("请输入入队元素个数:");
|
||||
scanf("%d", &n);
|
||||
printf("请输入需要入队的%d个元素:",n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
scanf("%d", &e);
|
||||
EnQueue(Q, e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int e;
|
||||
DelQueue(Q, e);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
printf("队列为:");
|
||||
Display(Q);
|
||||
break;
|
||||
case 6:
|
||||
exit(0);
|
||||
default:
|
||||
printf("无效选项\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
256
datastructure/2025301205+施光甲+实验二.cpp
Normal file
256
datastructure/2025301205+施光甲+实验二.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct PNode
|
||||
{
|
||||
int index; //指数
|
||||
int coe; // 系数
|
||||
struct PNode *next; //指针域
|
||||
}PNode,*Polynomial;
|
||||
|
||||
// 初始化三个多项式链表
|
||||
void chushihua(Polynomial *L, Polynomial *M, Polynomial *N)
|
||||
{
|
||||
//todo list 1: 为三个链表分配头节点并初始化
|
||||
*L = (Polynomial)malloc(sizeof(PNode));
|
||||
(*L)->next = NULL;
|
||||
*M = (Polynomial)malloc(sizeof(PNode));
|
||||
(*M)->next = NULL;
|
||||
*N = (Polynomial)malloc(sizeof(PNode));
|
||||
(*N)->next = NULL;
|
||||
}
|
||||
|
||||
// 判断链表是否为空
|
||||
void Emp(Polynomial L)
|
||||
{
|
||||
if (L->next == NULL)
|
||||
printf("链表为空表。\n");
|
||||
else
|
||||
printf("链表为非空表。\n");
|
||||
}
|
||||
|
||||
// 求链表长度
|
||||
void Length(Polynomial L)
|
||||
{
|
||||
PNode *p;
|
||||
int length = 0;
|
||||
//todo list 2: 遍历链表统计节点个数
|
||||
p = L->next;
|
||||
while (p != NULL) {
|
||||
length++;
|
||||
p = p->next;
|
||||
}
|
||||
printf("链表长度为:%d\n", length);
|
||||
}
|
||||
|
||||
// 1、构造两个按指数递增的有序链表:插入节点,创建一元多项式
|
||||
// 1、构造两个按指数递增的有序链表:插入节点,创建一元多项式
|
||||
void charu_1(Polynomial L) {
|
||||
PNode *q, *p;
|
||||
int n, i;
|
||||
printf("请输入你要创建的一元多项式的项数:\n");
|
||||
scanf("%d", &n);
|
||||
for (i = 1; i <= n; i++) {
|
||||
p = L;
|
||||
q = (Polynomial)malloc(sizeof(PNode));
|
||||
printf("请输入第%d项的系数和指数:", i);
|
||||
scanf("%d%d", &q->coe, &q->index);
|
||||
q->next = NULL;
|
||||
|
||||
// 查找插入位置,保持指数递增
|
||||
while (p->next != NULL && p->next->index < q->index) {
|
||||
//todo list 3: p指针移动到合适的位置
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
// 直接插入,不合并相同指数的项
|
||||
//todo list 4: 将*q结点插入到*p结点后
|
||||
q->next = p->next;
|
||||
p->next = q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 显示函数 - 使用H分隔系数和指数
|
||||
void xianshi(Polynomial L)
|
||||
{
|
||||
PNode *p;
|
||||
p = L->next;
|
||||
if (p == NULL) {
|
||||
printf("多项式为空");
|
||||
return;
|
||||
}
|
||||
while (p != NULL)
|
||||
{
|
||||
printf("%dH%d", p->coe, p->index); // 系数H指数
|
||||
p = p->next;
|
||||
if (p != NULL) {
|
||||
printf(" "); // 项之间的分隔
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
//2、两个一元多项式相加
|
||||
void hebiao(Polynomial J, Polynomial O, Polynomial H)
|
||||
{
|
||||
PNode *p = J->next, *q = O->next, *r = H, *s;
|
||||
|
||||
// 初始化结果链表
|
||||
H->next = NULL;
|
||||
|
||||
while (p != NULL && q != NULL) {
|
||||
if (p->index < q->index) {
|
||||
s = (Polynomial)malloc(sizeof(PNode));
|
||||
//todo list 5: 复制p节点的数据到新节点s
|
||||
s->coe = p->coe;
|
||||
s->index = p->index;
|
||||
s->next = NULL;
|
||||
//todo list 6: 将s节点插入到结果链表H的末尾
|
||||
r->next = s;
|
||||
r = s;
|
||||
p = p->next;
|
||||
} else if (p->index > q->index) {
|
||||
s = (Polynomial)malloc(sizeof(PNode));
|
||||
//todo list 7: 复制q节点的数据到新节点s
|
||||
s->coe = q->coe;
|
||||
s->index = q->index;
|
||||
s->next = NULL;
|
||||
//todo list 8: 将s节点插入到结果链表H的末尾
|
||||
r->next = s;
|
||||
r = s;
|
||||
q = q->next;
|
||||
} else {
|
||||
//todo list 9: 处理指数相等的项
|
||||
int sum = p->coe + q->coe;
|
||||
if (sum != 0) {
|
||||
s = (Polynomial)malloc(sizeof(PNode));
|
||||
s->index = p->index;
|
||||
s->coe = sum;
|
||||
s->next = NULL;
|
||||
//todo list 10: 将合并后的项插入结果链表
|
||||
r->next = s;
|
||||
r = s;
|
||||
}
|
||||
p = p->next;
|
||||
q = q->next;
|
||||
}
|
||||
}
|
||||
|
||||
//todo list 11: 处理剩余节点 - 多项式J
|
||||
while (p != NULL) {
|
||||
s = (Polynomial)malloc(sizeof(PNode));
|
||||
s->coe = p->coe;
|
||||
s->index = p->index;
|
||||
s->next = NULL;
|
||||
r->next = s;
|
||||
r = s;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
//todo list 12: 处理剩余节点 - 多项式O
|
||||
while (q != NULL) {
|
||||
s = (Polynomial)malloc(sizeof(PNode));
|
||||
s->coe = q->coe;
|
||||
s->index = q->index;
|
||||
s->next = NULL;
|
||||
r->next = s;
|
||||
r = s;
|
||||
q = q->next;
|
||||
}
|
||||
|
||||
printf("两个多项式相加的结果为:");
|
||||
xianshi(H);
|
||||
}
|
||||
|
||||
// 清空链表函数
|
||||
void clearList(Polynomial L) {
|
||||
PNode *p = L->next;
|
||||
while (p != NULL) {
|
||||
PNode *temp = p;
|
||||
p = p->next;
|
||||
free(temp);
|
||||
}
|
||||
L->next = NULL;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Polynomial head[3];
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
head[i] = (Polynomial)malloc(sizeof(PNode));
|
||||
head[i]->next = NULL;
|
||||
}
|
||||
|
||||
int choose = -1;
|
||||
|
||||
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("********** 0.退出 *******\n");
|
||||
printf("*********************************************************\n");
|
||||
|
||||
while (choose != 0) {
|
||||
printf("请输入你的选择项:");
|
||||
scanf("%d", &choose);
|
||||
|
||||
// 在switch外部声明变量
|
||||
PNode *temp;
|
||||
|
||||
switch (choose) {
|
||||
case 1:
|
||||
chushihua(&head[0], &head[1], &head[2]);
|
||||
printf("链表已经初始化。\n");
|
||||
break;
|
||||
case 2:
|
||||
for (i = 0; i < 2; i++) {
|
||||
printf("创建的第%d个一元多项式:\n", i+1);
|
||||
charu_1(head[i]);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
printf("显示第1个链表:");
|
||||
xianshi(head[0]);
|
||||
printf("显示第2个链表:");
|
||||
xianshi(head[1]);
|
||||
break;
|
||||
case 4:
|
||||
printf("计算第1个链表的长度:");
|
||||
Length(head[0]);
|
||||
printf("计算第2个链表的长度:");
|
||||
Length(head[1]);
|
||||
break;
|
||||
case 5:
|
||||
printf("判断第1个链表是否为空:");
|
||||
Emp(head[0]);
|
||||
printf("判断第2个链表是否为空:");
|
||||
Emp(head[1]);
|
||||
break;
|
||||
case 6:
|
||||
// 先清空结果链表
|
||||
clearList(head[2]);
|
||||
hebiao(head[0], head[1], head[2]);
|
||||
break;
|
||||
case 0:
|
||||
printf("程序退出,感谢使用!\n");
|
||||
// 释放内存
|
||||
for (i = 0; i < 3; i++) {
|
||||
clearList(head[i]);
|
||||
free(head[i]);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
printf("输入错误,请重新输入!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
114
datastructure/2025301205+施光甲+实验五.cpp
Normal file
114
datastructure/2025301205+施光甲+实验五.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int nextval[20];
|
||||
|
||||
int BF(char a[], char b[])
|
||||
{
|
||||
int i = 1;
|
||||
int j = 1;
|
||||
while (i <= strlen(a) && j <= strlen(b))
|
||||
{
|
||||
//todo list 比较数组a、b里对应位置的字符:
|
||||
if (a[i - 1] == b[j - 1]) {
|
||||
// 若匹配成功,则继续比较后续字符;
|
||||
i++;
|
||||
j++;
|
||||
} else {
|
||||
// 若匹配不成功,i指针、j指针回退,重新开始匹配
|
||||
i = i - j + 2;
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (j > strlen(b))
|
||||
{
|
||||
printf("BF算法匹配成功\n");
|
||||
//todo list //返回和模式b中第一个字符相等的字符在主串a中的序号
|
||||
return i - strlen(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("BF算法匹配失败\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Nextval(char b[])
|
||||
{
|
||||
nextval[1] = 0;
|
||||
int i = 1, j = 0;
|
||||
//todo list while 循环求nextval
|
||||
while (i < strlen(b)) {
|
||||
if (j == 0 || b[i - 1] == b[j - 1]) {
|
||||
i++;
|
||||
j++;
|
||||
if (b[i - 1] != b[j - 1]) {
|
||||
nextval[i] = j;
|
||||
} else {
|
||||
nextval[i] = nextval[j];
|
||||
}
|
||||
} else {
|
||||
j = nextval[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int KMP(char a[], char b[])
|
||||
{
|
||||
int i = 1, j = 1, k;
|
||||
Nextval(b); //求b串中所有字符的nextval值
|
||||
for (k = 1; k <= strlen(b); k++)
|
||||
{
|
||||
printf("nextval[%d]为:%4d\n", k, nextval[k]);
|
||||
}
|
||||
|
||||
while (i <= strlen(a) && j <= strlen(b))
|
||||
{
|
||||
//todo list 比较数组a、b里对应位置的字符:
|
||||
if (j == 0 || a[i - 1] == b[j - 1]) {
|
||||
// 若匹配成功,则继续比较后续字符;
|
||||
i++;
|
||||
j++;
|
||||
} else {
|
||||
// 若匹配不成功,利用nextval[j]实现j指针回退,重新开始匹配
|
||||
j = nextval[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (j > strlen(b))
|
||||
{
|
||||
printf("KMP算法匹配成功!\n");
|
||||
//todo list
|
||||
//返回和模式b中第一个字符相等的字符在主串a中的序号
|
||||
return i - strlen(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("KMP算法匹配失败!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char a[100], b[20];
|
||||
printf("请输入主串:\n");
|
||||
scanf("%s", a);
|
||||
// gets_s(a);
|
||||
printf("请输入子串:\n");
|
||||
scanf("%s", b);
|
||||
// gets_s(b);
|
||||
printf("----------------------------------------\n");
|
||||
|
||||
int num_BF, num_KMP;
|
||||
num_BF = BF(a, b);
|
||||
printf("BF:子串的第一个字符在主串中的位置为:%d\n", num_BF);
|
||||
printf("----------------------------------------\n");
|
||||
|
||||
num_KMP = KMP(a, b);
|
||||
printf("KMP:子串的第一个字符在主串中的位置为:%d", num_KMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
198
datastructure/2025301205+施光甲+实验六.cpp
Normal file
198
datastructure/2025301205+施光甲+实验六.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define OK 1
|
||||
typedef int Status;
|
||||
typedef struct BiTNode
|
||||
{
|
||||
char data; //结点数据域
|
||||
struct BiTNode *lchild, *rchild; //左右孩子指针
|
||||
}BiTNode,*BiTree;
|
||||
|
||||
//1、创建二叉链表:按先序次序输入二叉树中结点的值,创建二叉链表表示的二叉树T
|
||||
// 例:建立课本P115图5.10(b)的二叉树--读入字符的顺序为:ABC##DE#G##F###(#表示空树)
|
||||
BiTree Create(BiTree &T)
|
||||
{
|
||||
char ch;
|
||||
printf("请输入一个字符:");
|
||||
scanf("%c",&ch);
|
||||
getchar(); //清空缓冲区,把遗留的\n清除
|
||||
//todo list //if: 如果输入的是'#',则建立一棵空树
|
||||
//else:否则,递归建立一个二叉树(注意:是按按先序次序创建的二叉树)
|
||||
if(ch == '#') {
|
||||
T = NULL; //建立空树
|
||||
} else {
|
||||
T = (BiTree)malloc(sizeof(BiTNode)); //创建新结点
|
||||
T->data = ch;
|
||||
T->lchild = NULL;
|
||||
T->rchild = NULL;
|
||||
T->lchild = Create(T->lchild); //递归创建左子树
|
||||
T->rchild = Create(T->rchild); //递归创建右子树
|
||||
}
|
||||
return T;
|
||||
}
|
||||
|
||||
//先序遍历二叉树
|
||||
Status PreOrder(BiTree &T)
|
||||
{
|
||||
//todo list //if: 如果是空树,则返回
|
||||
//else:否则,先访问根结点 (D)
|
||||
//前序遍历左子树 (L)
|
||||
//前序遍历右子树 (R)
|
||||
if(T == NULL) {
|
||||
return OK;
|
||||
} else {
|
||||
printf("%c ", T->data); //访问根结点
|
||||
PreOrder(T->lchild); //前序遍历左子树
|
||||
PreOrder(T->rchild); //前序遍历右子树
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
//中序遍历二叉树
|
||||
Status InOrder(BiTree &T)
|
||||
{
|
||||
//todo list //if: 如果是空树,则返回
|
||||
//else:否则,先中序遍历左子树 (L)
|
||||
//访问根结点 (D)
|
||||
//中序遍历右子树 (R)
|
||||
if(T == NULL) {
|
||||
return OK;
|
||||
} else {
|
||||
InOrder(T->lchild); //中序遍历左子树
|
||||
printf("%c ", T->data); //访问根结点
|
||||
InOrder(T->rchild); //中序遍历右子树
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
//后序遍历
|
||||
Status PostOrder(BiTree &T)
|
||||
{
|
||||
//todo list //if: 如果是空树,则返回
|
||||
//else:否则,先后序遍历左子树 (L)
|
||||
//后序遍历右子树 (R)
|
||||
//访问根结点 (D)
|
||||
if(T == NULL) {
|
||||
return OK;
|
||||
} else {
|
||||
PostOrder(T->lchild); //后序遍历左子树
|
||||
PostOrder(T->rchild); //后序遍历右子树
|
||||
printf("%c ", T->data); //访问根结点
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
//层次遍历1
|
||||
void LeverOrder(BiTree &T)
|
||||
{
|
||||
if (T == NULL) { // 处理空树,避免空指针访问
|
||||
printf("二叉树为空!\n");
|
||||
return;
|
||||
}
|
||||
//BT *Queue[100]; //队列
|
||||
BiTree Queue[100]; //队列
|
||||
char ch;
|
||||
int front = 0;
|
||||
int rear = 0;
|
||||
// 队列边界检查(新增:防止数组越界)
|
||||
if (rear >= 100) {
|
||||
printf("队列已满,无法入队!\n");
|
||||
return;
|
||||
}
|
||||
Queue[rear++] = T; //根节点入队
|
||||
while (front < rear) //当队不空
|
||||
{
|
||||
ch = Queue[front]->data; //出队队头元素
|
||||
printf("%c ",ch);
|
||||
if (Queue[front]->lchild){
|
||||
if (rear >= 100) {
|
||||
printf("队列已满,左孩子无法入队!\n");
|
||||
break;
|
||||
}
|
||||
Queue[rear++] = Queue[front]->lchild;
|
||||
}
|
||||
if (Queue[front]->rchild){
|
||||
if (rear >= 100) {
|
||||
printf("队列已满,右孩子无法入队!\n");
|
||||
break;
|
||||
}
|
||||
Queue[rear++] = Queue[front]->rchild;
|
||||
}
|
||||
front++; // 队头后移,完成出队
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//节点总数
|
||||
int Count(BiTree &T)
|
||||
{
|
||||
//todo list //if:如果是空树,则结点个数为0;
|
||||
//else:否则,结点个数为左子树的结点个数+右子树的结点个数再+1。
|
||||
if(T == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return Count(T->lchild) + Count(T->rchild) + 1;
|
||||
}
|
||||
}
|
||||
//叶子节点
|
||||
int CountLeaf(BiTree &T)
|
||||
{
|
||||
//todo list //if:如果是空树,则叶子结点个数为0;
|
||||
//else if:如果是叶子结点,则返回1;
|
||||
//else否则,为左子树的叶子结点个数+右子树的叶子结点个数。
|
||||
if(T == NULL) {
|
||||
return 0;
|
||||
} else if(T->lchild == NULL && T->rchild == NULL) {
|
||||
return 1;
|
||||
} else {
|
||||
return CountLeaf(T->lchild) + CountLeaf(T->rchild);
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
BiTree T = NULL; //创建一颗空树
|
||||
int choose = -1;
|
||||
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("\n");
|
||||
printf("请输入你的选择项:");
|
||||
scanf("%d", &choose);
|
||||
getchar(); //清空缓冲区,把遗留的\n清除
|
||||
switch (choose)
|
||||
{
|
||||
case 1:T = Create(T); break; //创建
|
||||
printf("\n");
|
||||
case 2:
|
||||
printf("先序序列为:") ;
|
||||
PreOrder(T); break; //先序遍历二叉树
|
||||
printf("\n");
|
||||
case 3:
|
||||
printf("中序序列为:") ;
|
||||
InOrder(T); break; //中序遍历二叉树
|
||||
printf("\n");
|
||||
case 4:
|
||||
printf("后序序列为:") ;
|
||||
PostOrder(T); break; //后序遍历二叉树
|
||||
printf("\n");
|
||||
case 5:
|
||||
printf("层次序列为:") ;
|
||||
LeverOrder(T); break; //层序遍历二叉树
|
||||
printf("\n");
|
||||
case 6:printf("节点总数为:%d\n", Count(T)); break;//结点总数
|
||||
case 7:printf("叶子节点总数为:%d\n", CountLeaf(T)); break; //叶子结点总数
|
||||
case 0:exit(0); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
153
datastructure/2025301205+施光甲+实验四.cpp
Normal file
153
datastructure/2025301205+施光甲+实验四.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAXSIZE 100
|
||||
|
||||
typedef struct Stack
|
||||
{
|
||||
char *base; //栈底指针
|
||||
char *top; //栈顶指针
|
||||
int stacksize; //栈可用的最大容量
|
||||
int length; //新增:用来判断栈是否为空
|
||||
}Stack;
|
||||
|
||||
//初始化
|
||||
void InitStack(Stack &p)
|
||||
{
|
||||
p.base = new char[MAXSIZE]; //分配空间
|
||||
//todo list 处理 栈顶指针top初始为base
|
||||
p.top = p.base;
|
||||
//todo list 处理stacksize、length
|
||||
p.stacksize = MAXSIZE;
|
||||
p.length = 0;
|
||||
}
|
||||
|
||||
#define OK 1
|
||||
#define ERROR 0
|
||||
typedef int Status;
|
||||
|
||||
//入栈
|
||||
Status Push(Stack &p, char e)
|
||||
{
|
||||
if(p.top - p.base == p.stacksize) // 栈满
|
||||
return ERROR;
|
||||
//todo list //将元素e压入栈顶
|
||||
*p.top = e;
|
||||
//todo list //栈顶指针加1
|
||||
p.top++;
|
||||
p.length++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
//出栈
|
||||
char Pop(Stack &p)
|
||||
{
|
||||
char e;
|
||||
if(p.top == p.base) // 栈空
|
||||
return '\0';
|
||||
//todo list //栈顶指针减1
|
||||
p.top--;
|
||||
//todo list //取栈顶元素
|
||||
e = *p.top;
|
||||
p.length--;
|
||||
return e;
|
||||
}
|
||||
|
||||
//1、判断是否为回文串
|
||||
void Palindrome(Stack &S, char a[])
|
||||
{
|
||||
int i;
|
||||
//栈清空
|
||||
S.top = S.base;
|
||||
S.length = 0;
|
||||
for (i = 0; a[i] != '\0'; i++){
|
||||
//todo list //for循环 把字符串全部入栈Push()
|
||||
Push(S, a[i]);
|
||||
}
|
||||
for (i = 0; a[i] != '\0'; i++){
|
||||
//todo list //for循环 对比串的两端元素,如果Pop(S) != a[i]则表明不是回文,退出
|
||||
if(Pop(S) != a[i]){
|
||||
printf("----不是回文----\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (i == strlen(a))
|
||||
{
|
||||
printf("------回文------\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("----不是回文----\n");
|
||||
}
|
||||
}
|
||||
|
||||
//2、括号匹配检验------可参考课本P75
|
||||
//只讨论由圆括号()和中括号[]组成的括号
|
||||
void Matching(Stack &S, char ch[])
|
||||
{
|
||||
int flag = 1; //flag初始为1,当 flag = 1时表示匹配成功
|
||||
int i=0;
|
||||
//栈清空
|
||||
S.top = S.base;
|
||||
S.length = 0;
|
||||
//todo list //while做括号匹配检验:
|
||||
while(ch[i] != '\0' && flag){
|
||||
//若为左括号,则将其入栈;
|
||||
if(ch[i] == '(' || ch[i] == '['){
|
||||
Push(S, ch[i]);
|
||||
}
|
||||
//若为右括号,则与出栈的栈顶元素进行比较,分析是否能够配对(如果不匹配,注意将flag置为0 )。
|
||||
else if(ch[i] == ')' || ch[i] == ']'){
|
||||
if(S.length == 0){
|
||||
flag = 0;
|
||||
}
|
||||
else{
|
||||
char left = Pop(S);
|
||||
if((ch[i] == ')' && left != '(') || (ch[i] == ']' && left != '[')){
|
||||
flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(S.length == 0 && flag ) //栈空且flag = 1时,括号匹配
|
||||
printf("-----括号匹配-----\n");
|
||||
else
|
||||
printf("----括号不匹配----\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char a[20], b[20];
|
||||
Stack s;
|
||||
InitStack(s);
|
||||
int choose = -1;
|
||||
printf("------------------------------\n");
|
||||
printf("1.判断是否是回文字符串\n");
|
||||
printf("2.判断括号是否匹配\n");
|
||||
printf("0.退出\n");
|
||||
printf("------------------------------\n");
|
||||
while(choose)
|
||||
{
|
||||
printf("请输入选项:");
|
||||
scanf("%d", &choose);
|
||||
switch(choose)
|
||||
{
|
||||
case 1:
|
||||
printf("请输入一个字符串:");
|
||||
scanf("%s",a);
|
||||
Palindrome(s, a);
|
||||
break;
|
||||
case 2:
|
||||
printf("请输入一个字符串(由圆括号和中括号组成):");
|
||||
scanf("%s",b);
|
||||
Matching(s, b);
|
||||
break;
|
||||
case 0:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user