课程代码

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

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

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

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

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

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