mirror of
https://github.com/kangjianwei/Data-Structure.git
synced 2026-02-06 08:21:44 +08:00
💡 <03 栈和队列>习题代码
This commit is contained in:
162
CLion/ExerciseBook/03.15/03.15.c
Normal file
162
CLion/ExerciseBook/03.15/03.15.c
Normal file
@@ -0,0 +1,162 @@
|
||||
#include <stdio.h>
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define N 100 //栈的容量
|
||||
|
||||
/* 双向栈元素类型定义 */
|
||||
typedef int SElemType;
|
||||
|
||||
/* 双向栈中包含的两个栈的栈名 */
|
||||
typedef enum {
|
||||
Left, Right
|
||||
} StackName;
|
||||
|
||||
/* 双向栈结构 */
|
||||
typedef struct {
|
||||
SElemType stack[N]; // 用一个容量足够大的数组做栈
|
||||
int top[2]; // 存放栈顶指针
|
||||
} TWS;
|
||||
|
||||
// 初始化栈
|
||||
Status Inistack_3_15(TWS* tws);
|
||||
|
||||
// 入栈,name指示向哪个栈中添加元素
|
||||
Status Push_3_15(TWS* tws, StackName name, SElemType x);
|
||||
|
||||
// 出栈,name指示从哪个栈中移除元素
|
||||
Status Pop_3_15(TWS* tws, StackName name, SElemType* x);
|
||||
|
||||
// 输出栈中元素,name指示输出哪个栈中的元素
|
||||
void OutputStack(TWS tws, StackName name);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
TWS S;
|
||||
int i, x;
|
||||
|
||||
printf("████████ 初始化栈...\n");
|
||||
Inistack_3_15(&S);
|
||||
|
||||
|
||||
printf("████████ 向两个栈中压入元素...\n");
|
||||
|
||||
for(i = 1; i <= 5; i++) {
|
||||
Push_3_15(&S, Left, i);
|
||||
Push_3_15(&S, Right, 2 * i);
|
||||
}
|
||||
printf("█ 左栈中的元素(从栈底到栈顶):");
|
||||
OutputStack(S, Left);
|
||||
printf("█ 右栈中的元素(从栈底到栈顶):");
|
||||
OutputStack(S, Right);
|
||||
|
||||
|
||||
printf("████████ 分别弹出两个栈的栈顶元素...\n");
|
||||
|
||||
Pop_3_15(&S, Left, &x);
|
||||
printf("█ 弹出左栈的栈顶元素为:%d\n", x);
|
||||
printf("█ 左栈中的元素(从栈底到栈顶):");
|
||||
OutputStack(S, Left);
|
||||
|
||||
Pop_3_15(&S, Right, &x);
|
||||
printf("█ 弹出右栈的栈顶元素为:%d\n", x);
|
||||
printf("█ 右栈中的元素(从栈底到栈顶):");
|
||||
OutputStack(S, Right);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 初始化栈
|
||||
Status Inistack_3_15(TWS* tws) {
|
||||
if(tws == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*tws).top[Left] = -1; // 栈0的栈顶指针,注意不是0
|
||||
(*tws).top[Right] = N; // 栈1的栈顶指针,注意不是N-1
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 入栈,name指示向哪个栈中添加元素
|
||||
Status Push_3_15(TWS* tws, StackName name, SElemType x) {
|
||||
if(tws == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 注意栈满条件,数组全被填充完才算栈满,不浪费空间
|
||||
if((*tws).top[Left] + 1 == (*tws).top[Right]) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 先移动栈顶游标,再存入元素
|
||||
switch(name) {
|
||||
case Left:
|
||||
(*tws).top[name]++; // 左边栈的游标向右移动
|
||||
break;
|
||||
case Right:
|
||||
(*tws).top[name]--; // 右边栈的游标向左移动
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 存入元素
|
||||
(*tws).stack[(*tws).top[name]] = x;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 出栈,name指示从哪个栈中移除元素
|
||||
Status Pop_3_15(TWS* tws, StackName name, SElemType* x) {
|
||||
if(tws == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 先移除元素,再移动游标
|
||||
switch(name) {
|
||||
case Left:
|
||||
// 判断左边的栈是否为空
|
||||
if((*tws).top[name] == -1) {
|
||||
return ERROR;
|
||||
}
|
||||
*x = (*tws).stack[(*tws).top[name]];
|
||||
(*tws).top[name]--;
|
||||
break;
|
||||
case Right:
|
||||
// 判断右边的栈是否为空
|
||||
if((*tws).top[name] == N) {
|
||||
return ERROR;
|
||||
}
|
||||
*x = (*tws).stack[(*tws).top[name]];
|
||||
(*tws).top[name]++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 输出栈中元素,name指示输出哪个栈中的元素
|
||||
void OutputStack(TWS tws, StackName name) {
|
||||
int i;
|
||||
|
||||
switch(name) {
|
||||
case Left:
|
||||
for(i = 0; i <= tws.top[name]; i++) {
|
||||
printf("%d ", tws.stack[i]);
|
||||
}
|
||||
break;
|
||||
case Right:
|
||||
for(i = N - 1; i >= tws.top[name]; i--) {
|
||||
printf("%d ", tws.stack[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
6
CLion/ExerciseBook/03.15/CMakeLists.txt
Normal file
6
CLion/ExerciseBook/03.15/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件,并链接公共库
|
||||
add_executable(03.15 03.15.c)
|
||||
target_link_libraries(03.15 Scanf_lib)
|
||||
136
CLion/ExerciseBook/03.16/03.16.c
Normal file
136
CLion/ExerciseBook/03.16/03.16.c
Normal file
@@ -0,0 +1,136 @@
|
||||
#include <stdio.h>
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 生成车厢调度序列,其中'I'代表入栈,'O'代表出栈
|
||||
*
|
||||
* 假设入口在右边,出口在左边,且车厢读取顺序【从左到右】
|
||||
*
|
||||
* En :等待调度的列车序列
|
||||
* seq:调度序列
|
||||
*/
|
||||
void Algo_3_16(char* En, char seq[]);
|
||||
|
||||
/*
|
||||
* 使用约定好的调度序列seq,将入口En处的车厢调度到出口Ex
|
||||
*
|
||||
* 该方法可看做是对调度序列的检验
|
||||
*
|
||||
* En :等待调度的列车序列
|
||||
* seq:调度序列
|
||||
* Ex :调度完成后的序列
|
||||
*/
|
||||
Status Dispatch(char* En, char* seq, char Ex[]);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* En = "HSHHSHHHSSHSSSHS"; // 等待调度的列车序列
|
||||
char Ex[100] = {'\0'}; // 调度完成的列车序列
|
||||
char seq[100] = {'\0'}; // 调度序列
|
||||
|
||||
printf("████ 入口处的序列:\n");
|
||||
printf("█ En = %s\n", En);
|
||||
|
||||
Algo_3_16(En, seq);
|
||||
printf("████ 生成的调度序列:\n");
|
||||
printf("█ seq = %s\n", seq);
|
||||
|
||||
Dispatch(En, seq, Ex);
|
||||
printf("████ 根据生成的调度序列,对入口处的车厢调度,调度完成后的车厢序列:\n");
|
||||
printf("█ Ex = %s\n", Ex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 生成车厢调度序列,其中'I'代表入栈,'O'代表出栈
|
||||
*
|
||||
* 假设入口在右边,出口在左边,车厢读取顺序从左到右
|
||||
*
|
||||
* En :等待调度的列车序列
|
||||
* seq:调度序列
|
||||
*/
|
||||
void Algo_3_16(char* En, char seq[]) {
|
||||
int i, j;
|
||||
SqStack S;
|
||||
SElemType e;
|
||||
|
||||
// 初始化一个中转栈
|
||||
InitStack(&S);
|
||||
|
||||
// 遍历待调度序列
|
||||
for(i = j = 0; En[i] != '\0'; i++) {
|
||||
// 遇到硬席,则将其入栈
|
||||
if(En[i] == 'H') {
|
||||
Push(&S, En[i]);
|
||||
seq[j++] = 'I';
|
||||
}
|
||||
|
||||
// 遇到软席,则先入栈,并立即出栈,相当于用栈做中转
|
||||
if(En[i] == 'S') {
|
||||
Push(&S, En[i]);
|
||||
Pop(&S, &e);
|
||||
seq[j++] = 'I';
|
||||
seq[j++] = 'O';
|
||||
}
|
||||
}
|
||||
|
||||
// 将中转栈中的硬席出栈
|
||||
while(!StackEmpty(S)) {
|
||||
Pop(&S, &e);
|
||||
seq[j++] = 'O';
|
||||
}
|
||||
|
||||
seq[j] = '\0';
|
||||
|
||||
DestroyStack(&S);
|
||||
}
|
||||
|
||||
/*
|
||||
* 使用约定好的调度序列seq,将入口En处的车厢调度到出口Ex
|
||||
*
|
||||
* 该方法可看做是对调度序列的检验
|
||||
*
|
||||
* En :等待调度的列车序列
|
||||
* seq:调度序列
|
||||
* Ex :调度完成后的序列
|
||||
*/
|
||||
Status Dispatch(char* En, char* seq, char Ex[]) {
|
||||
int i, j, k;
|
||||
SqStack S;
|
||||
SElemType e;
|
||||
|
||||
// 初始化一个中转栈
|
||||
InitStack(&S);
|
||||
|
||||
i = j = k = 0;
|
||||
|
||||
// 遍历调度序列
|
||||
while(seq[k] != '\0') {
|
||||
// 遇到入栈标记,则将车厢加入中转栈
|
||||
if(seq[k] == 'I') {
|
||||
Push(&S, En[i++]);
|
||||
}
|
||||
|
||||
// 遇到出栈标记,则将车厢移除,并转移到出口处
|
||||
if(seq[k] == 'O') {
|
||||
Pop(&S, &e);
|
||||
Ex[j++] = e;
|
||||
}
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
// 如果调度序列为空,但是入口处存在未调度的车厢,或者中转栈里存在未处理的车厢,则表示发生错误
|
||||
if(seq[k] == '\0' && (En[i] || StackEmpty(S))) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Ex[j] = '\0';
|
||||
|
||||
DestroyStack(&S);
|
||||
|
||||
return OK;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.16/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.16/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.16 SqStack.h SqStack.c 03.16.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.16 Scanf_lib)
|
||||
109
CLion/ExerciseBook/03.16/SqStack.c
Normal file
109
CLion/ExerciseBook/03.16/SqStack.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 销毁(结构)
|
||||
*
|
||||
* 释放顺序栈所占内存。
|
||||
*/
|
||||
Status DestroyStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
free((*S).base);
|
||||
|
||||
(*S).base = NULL;
|
||||
(*S).top = NULL;
|
||||
(*S).stacksize = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S) {
|
||||
if(S.top == S.base) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 栈满时,追加存储空间
|
||||
if((*S).top - (*S).base >= (*S).stacksize) {
|
||||
(*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW); // 存储分配失败
|
||||
}
|
||||
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
// 进栈先赋值,栈顶指针再自增
|
||||
*(S->top++) = e;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if((*S).top == (*S).base) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 出栈栈顶指针先递减,再赋值
|
||||
*e = *(--(*S).top);
|
||||
|
||||
return OK;
|
||||
}
|
||||
66
CLion/ExerciseBook/03.16/SqStack.h
Normal file
66
CLion/ExerciseBook/03.16/SqStack.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#ifndef SQSTACK_H
|
||||
#define SQSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量
|
||||
|
||||
/* 顺序栈元素类型定义 */
|
||||
typedef int SElemType;
|
||||
|
||||
// 顺序栈元素结构
|
||||
typedef struct {
|
||||
SElemType* base; // 栈底指针
|
||||
SElemType* top; // 栈顶指针
|
||||
int stacksize; // 当前已分配的存储空间,以元素为单位
|
||||
} SqStack;
|
||||
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 销毁(结构)
|
||||
*
|
||||
* 释放顺序栈所占内存。
|
||||
*/
|
||||
Status DestroyStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S);
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e);
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e);
|
||||
|
||||
#endif
|
||||
69
CLion/ExerciseBook/03.17/03.17.c
Normal file
69
CLion/ExerciseBook/03.17/03.17.c
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <stdio.h>
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 判定输入序列是否为"序列1&序列2"这种模式
|
||||
* 其中,序列2是序列1的逆置
|
||||
*
|
||||
* s:待验证的序列,以'@'符号结尾
|
||||
*/
|
||||
Status Algo_3_17(char* s);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* s = "a+b-c&c-b+a@";
|
||||
|
||||
printf("判断序列 %s 是否合规...\n", s);
|
||||
|
||||
if(Algo_3_17(s)) {
|
||||
printf("█ 序列满足题意!\n");
|
||||
} else {
|
||||
printf("█ 序列不满足题意!!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 判定输入序列是否为"序列1&序列2"这种模式
|
||||
* 其中,序列2是序列1的逆置
|
||||
*
|
||||
* s:待验证的序列,以'@'符号结尾
|
||||
*/
|
||||
Status Algo_3_17(char* s) {
|
||||
SqStack S;
|
||||
SElemType e;
|
||||
int i;
|
||||
|
||||
InitStack(&S);
|
||||
i = 0;
|
||||
|
||||
// 将'&'前的序列入栈
|
||||
while(s[i] != '@' && s[i] != '&') {
|
||||
Push(&S, s[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
// 如果遇到了'&'符号
|
||||
if(s[i] != '@') {
|
||||
i++; // 跳过&符号
|
||||
|
||||
// 将'&'后的序列出栈
|
||||
while(!StackEmpty(S) && s[i] != '@') {
|
||||
Pop(&S, &e);
|
||||
if(s[i] != e) {
|
||||
return ERROR;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果栈为空,且序列恰好访问完,说明符合题意
|
||||
if(StackEmpty(S) && s[i] == '@') {
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.17/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.17/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.17 SqStack.h SqStack.c 03.17.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.17 Scanf_lib)
|
||||
90
CLion/ExerciseBook/03.17/SqStack.c
Normal file
90
CLion/ExerciseBook/03.17/SqStack.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S) {
|
||||
if(S.top == S.base) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 栈满时,追加存储空间
|
||||
if((*S).top - (*S).base >= (*S).stacksize) {
|
||||
(*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW); // 存储分配失败
|
||||
}
|
||||
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
// 进栈先赋值,栈顶指针再自增
|
||||
*(S->top++) = e;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if((*S).top == (*S).base) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 出栈栈顶指针先递减,再赋值
|
||||
*e = *(--(*S).top);
|
||||
|
||||
return OK;
|
||||
}
|
||||
59
CLion/ExerciseBook/03.17/SqStack.h
Normal file
59
CLion/ExerciseBook/03.17/SqStack.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#ifndef SQSTACK_H
|
||||
#define SQSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量
|
||||
|
||||
/* 顺序栈元素类型定义 */
|
||||
typedef int SElemType;
|
||||
|
||||
// 顺序栈元素结构
|
||||
typedef struct {
|
||||
SElemType* base; // 栈底指针
|
||||
SElemType* top; // 栈顶指针
|
||||
int stacksize; // 当前已分配的存储空间,以元素为单位
|
||||
} SqStack;
|
||||
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S);
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e);
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e);
|
||||
|
||||
#endif
|
||||
72
CLion/ExerciseBook/03.18/03.18.c
Normal file
72
CLion/ExerciseBook/03.18/03.18.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include <stdio.h>
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 判定表达式开闭括号是否配对出现
|
||||
*
|
||||
*【注】
|
||||
* 只是判断括号是否配对出现,而不是判断括号类型、顺序是否正确
|
||||
*/
|
||||
Status Algo_3_18(char* s);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* s = "(1+2)*3/{2/[(4-5)*3]-5*(8-7)}";
|
||||
|
||||
printf("判断表达式 %s 开闭括号数量是否匹配...\n", s);
|
||||
|
||||
if(Algo_3_18(s) == TRUE) {
|
||||
printf("█ 表达式开闭括号数量匹配!\n");
|
||||
} else {
|
||||
printf("█ 表达式开闭括号数量不匹配!!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 判定表达式开闭括号是否配对出现
|
||||
*
|
||||
*【注】
|
||||
* 只是判断括号是否配对出现,而不是判断括号类型、顺序是否正确
|
||||
*/
|
||||
Status Algo_3_18(char* s) {
|
||||
SqStack S;
|
||||
SElemType e;
|
||||
int i;
|
||||
|
||||
InitStack(&S);
|
||||
|
||||
for(i = 0; s[i] != '\0'; i++) {
|
||||
switch(s[i]) {
|
||||
// 遇到左括号,则入栈
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
Push(&S, s[i]);
|
||||
break;
|
||||
|
||||
// 遇到右括号,则出栈
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
if(StackEmpty(S)) {
|
||||
return ERROR;
|
||||
}
|
||||
Pop(&S, &e);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果栈正好为空了,说明校验成功
|
||||
if(StackEmpty(S)) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.18/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.18/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.18 SqStack.h SqStack.c 03.18.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.18 Scanf_lib)
|
||||
90
CLion/ExerciseBook/03.18/SqStack.c
Normal file
90
CLion/ExerciseBook/03.18/SqStack.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S) {
|
||||
if(S.top == S.base) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 栈满时,追加存储空间
|
||||
if((*S).top - (*S).base >= (*S).stacksize) {
|
||||
(*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW); // 存储分配失败
|
||||
}
|
||||
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
// 进栈先赋值,栈顶指针再自增
|
||||
*(S->top++) = e;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if((*S).top == (*S).base) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 出栈栈顶指针先递减,再赋值
|
||||
*e = *(--(*S).top);
|
||||
|
||||
return OK;
|
||||
}
|
||||
59
CLion/ExerciseBook/03.18/SqStack.h
Normal file
59
CLion/ExerciseBook/03.18/SqStack.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#ifndef SQSTACK_H
|
||||
#define SQSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量
|
||||
|
||||
/* 顺序栈元素类型定义 */
|
||||
typedef int SElemType;
|
||||
|
||||
// 顺序栈元素结构
|
||||
typedef struct {
|
||||
SElemType* base; // 栈底指针
|
||||
SElemType* top; // 栈顶指针
|
||||
int stacksize; // 当前已分配的存储空间,以元素为单位
|
||||
} SqStack;
|
||||
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S);
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e);
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e);
|
||||
|
||||
#endif
|
||||
98
CLion/ExerciseBook/03.19/03.19.c
Normal file
98
CLion/ExerciseBook/03.19/03.19.c
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <stdio.h>
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
// 判定表达式开闭括号是否配对出现,且类型是否匹配
|
||||
Status Algo_3_19(char* s);
|
||||
|
||||
// 判断括号a和括号b之间的类型是否匹配
|
||||
Status Matching(char a, char b);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* s = "(1+2)*3/{2/[(4-5)*3]-5*(8-7)}";
|
||||
|
||||
printf("判断表达式 %s 括号是否匹配...\n", s);
|
||||
|
||||
if(Algo_3_19(s)) {
|
||||
printf("█ 表达式括号匹配!\n");
|
||||
} else {
|
||||
printf("█ 表达式括号不匹配!!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 判定表达式开闭括号是否配对出现,且类型是否匹配
|
||||
Status Algo_3_19(char* s) {
|
||||
SqStack S;
|
||||
SElemType e;
|
||||
int i;
|
||||
|
||||
InitStack(&S);
|
||||
|
||||
for(i = 0; s[i] != '\0'; i++) {
|
||||
switch(s[i]) {
|
||||
// 遇到左括号,则入栈
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
Push(&S, s[i]);
|
||||
break;
|
||||
|
||||
// 遇到右括号,则出栈
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
if(StackEmpty(S)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Pop(&S, &e);
|
||||
|
||||
// 判断括号是否匹配
|
||||
if(!Matching(e, s[i])) {
|
||||
return ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(StackEmpty(S)) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 判断括号a和括号b之间的类型是否匹配
|
||||
Status Matching(char a, char b) {
|
||||
switch(a) {
|
||||
case '(':
|
||||
if(b != ')') {
|
||||
return ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '[':
|
||||
if(b != ']') {
|
||||
return ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '{':
|
||||
if(b != '}') {
|
||||
return ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.19/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.19/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.19 SqStack.h SqStack.c 03.19.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.19 Scanf_lib)
|
||||
90
CLion/ExerciseBook/03.19/SqStack.c
Normal file
90
CLion/ExerciseBook/03.19/SqStack.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S) {
|
||||
if(S.top == S.base) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 栈满时,追加存储空间
|
||||
if((*S).top - (*S).base >= (*S).stacksize) {
|
||||
(*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW); // 存储分配失败
|
||||
}
|
||||
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
// 进栈先赋值,栈顶指针再自增
|
||||
*(S->top++) = e;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if((*S).top == (*S).base) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 出栈栈顶指针先递减,再赋值
|
||||
*e = *(--(*S).top);
|
||||
|
||||
return OK;
|
||||
}
|
||||
59
CLion/ExerciseBook/03.19/SqStack.h
Normal file
59
CLion/ExerciseBook/03.19/SqStack.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#ifndef SQSTACK_H
|
||||
#define SQSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量
|
||||
|
||||
/* 顺序栈元素类型定义 */
|
||||
typedef int SElemType;
|
||||
|
||||
// 顺序栈元素结构
|
||||
typedef struct {
|
||||
SElemType* base; // 栈底指针
|
||||
SElemType* top; // 栈顶指针
|
||||
int stacksize; // 当前已分配的存储空间,以元素为单位
|
||||
} SqStack;
|
||||
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S);
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e);
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e);
|
||||
|
||||
#endif
|
||||
220
CLion/ExerciseBook/03.20/03.20.c
Normal file
220
CLion/ExerciseBook/03.20/03.20.c
Normal file
@@ -0,0 +1,220 @@
|
||||
#include <stdio.h>
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 此算法类似于迷宫寻路算法 */
|
||||
|
||||
/* 宏定义 */
|
||||
#define SleepTime 2
|
||||
#define Row 10
|
||||
#define Col 17
|
||||
|
||||
/* 访问方向 */
|
||||
typedef enum {
|
||||
East, South, West, North
|
||||
} Direction;
|
||||
|
||||
/* 颜色枚举 */
|
||||
typedef enum {
|
||||
Color_1, Color_2, Color_3
|
||||
} Color;
|
||||
|
||||
/* 栈的元素类型 */
|
||||
typedef struct {
|
||||
int x, y; // 像素点的横、纵坐标定义
|
||||
int di; // 从此像素点走向下一像素点的"方向"
|
||||
} SElemType;
|
||||
|
||||
// 迷宫染色函数:对指定的图像染色
|
||||
void Algo_3_20(int g[][17], SElemType start);
|
||||
|
||||
// 初始化图像区域和染色起点
|
||||
void InitGrap(int g[][17], SElemType* start);
|
||||
|
||||
// 在屏幕上显示当前图像
|
||||
void PaintGrap(int g[][17]);
|
||||
|
||||
// 判断某个点是否需要染色
|
||||
Status Pass(SElemType e, int g[][17]);
|
||||
|
||||
// 遇到可以染色的点即留下标记,即染上相应的颜色
|
||||
void Mark(SElemType* e, int g[][17]);
|
||||
|
||||
// 获取下一个该染色的点的信息
|
||||
Status NextPos(SElemType* e);
|
||||
|
||||
// 判断当前的点是否出界
|
||||
Status IsCross(SElemType e);
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int g[Row][Col]; // 存放图像区域点的颜色
|
||||
SElemType start; // 染色的起点
|
||||
|
||||
InitGrap(g, &start);
|
||||
PaintGrap(g);
|
||||
|
||||
Algo_3_20(g, start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 对指定的图像染色
|
||||
void Algo_3_20(int g[][Col], SElemType start) {
|
||||
SElemType e;
|
||||
SElemType stack[10000]; // 定义一个足够大的数组作为栈,存放染过色的点
|
||||
int top = -1; // 栈顶指针
|
||||
|
||||
e = start;
|
||||
do {
|
||||
// 如果需要染色
|
||||
if(Pass(e, g)) {
|
||||
Mark(&e, g); // 将其染色,并标记其前进方向
|
||||
PaintGrap(g);
|
||||
stack[++top] = e; // 将访问过的像素点入栈
|
||||
NextPos(&e); // 得出下一个像素点信息
|
||||
} else {
|
||||
if(top != -1) {
|
||||
e = stack[top--];
|
||||
|
||||
// 栈中弹出的点已没多余方向可访问
|
||||
while(e.di == North && top != -1) {
|
||||
e = stack[top--];
|
||||
}
|
||||
|
||||
if(e.di < North) {
|
||||
e.di++;
|
||||
stack[++top] = e;
|
||||
NextPos(&e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(top != -1); // 栈不为空
|
||||
}
|
||||
|
||||
/* 初始化图像区域和染色起点 */
|
||||
void InitGrap(int g[][Col], SElemType* start) {
|
||||
int i, j;
|
||||
|
||||
// 储存颜色0和颜色1
|
||||
int a[Row][Col]={{0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0},
|
||||
{0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,0},
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
|
||||
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
|
||||
{0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0},
|
||||
{0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}};
|
||||
|
||||
for(i = 0; i < 10; i++) {
|
||||
for(j = 0; j < 17; j++) {
|
||||
g[i][j] = a[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
(*start).x = 9; // 起点坐标
|
||||
(*start).y = 8;
|
||||
(*start).di = East; // East代表方向向右
|
||||
}
|
||||
|
||||
/* 在屏幕上显示当前图像 */
|
||||
void PaintGrap(int g[][Col]) {
|
||||
int i, j;
|
||||
|
||||
Wait(SleepTime);
|
||||
|
||||
for(i = 0; i < Row; i++) {
|
||||
for(j = 0; j < Col; j++) {
|
||||
// 颜色0用"^"显示
|
||||
if(g[i][j] == Color_1) {
|
||||
printf(".");
|
||||
}
|
||||
|
||||
// 颜色1显示为空白
|
||||
if(g[i][j] == Color_2) {
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
// 颜色2用"*"显示
|
||||
if(g[i][j] == Color_3) {
|
||||
printf("*");
|
||||
}
|
||||
|
||||
if(j && !(j % (Col - 1))) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* 判断某个点是否需要染色 */
|
||||
Status Pass(SElemType e, int g[][Col]) {
|
||||
int x = e.x;
|
||||
int y = e.y;
|
||||
|
||||
// 将颜色为1的点染成其他颜色
|
||||
if(g[x][y] == 1) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* 遇到可以染色的点即留下标记,即染上相应的颜色 */
|
||||
void Mark(SElemType* e, int g[][Col]) {
|
||||
int x = (*e).x;
|
||||
int y = (*e).y;
|
||||
|
||||
(*e).di = East; // 标记此像素点的前进方向
|
||||
|
||||
g[x][y] = 2; // 将此像素点颜色染为颜色2
|
||||
}
|
||||
|
||||
/* 获取下一个该染色的点的信息 */
|
||||
Status NextPos(SElemType* e) {
|
||||
SElemType tmp;
|
||||
tmp = *e;
|
||||
|
||||
switch(tmp.di) {
|
||||
case East:
|
||||
(tmp.y)++; // East代表向右
|
||||
break;
|
||||
case South:
|
||||
(tmp.x)++; // South代表向下
|
||||
break;
|
||||
case West:
|
||||
(tmp.y)--; // West代表向左
|
||||
break;
|
||||
case North:
|
||||
(tmp.x)--; // North代表向上
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(IsCross(tmp)) {
|
||||
++(*e).di;
|
||||
NextPos(e);
|
||||
} else {
|
||||
*e = tmp;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* 判断当前的点是否出界 */
|
||||
Status IsCross(SElemType e) {
|
||||
int x = e.x;
|
||||
int y = e.y;
|
||||
|
||||
// 越界
|
||||
if(x < 0 || y < 0 || x > Row - 1 || y > Col - 1) {
|
||||
return OK;
|
||||
} else {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
6
CLion/ExerciseBook/03.20/CMakeLists.txt
Normal file
6
CLion/ExerciseBook/03.20/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件,并链接公共库
|
||||
add_executable(03.20 03.20.c)
|
||||
target_link_libraries(03.20 Scanf_lib)
|
||||
124
CLion/ExerciseBook/03.21/03.21.c
Normal file
124
CLion/ExerciseBook/03.21/03.21.c
Normal file
@@ -0,0 +1,124 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h> // 提供strlen原型
|
||||
#include <ctype.h> // 提供isalpha原型
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
// 运算符表,即表达式中允许出现的符号
|
||||
static const char OP[] = {'+', '-', '*', '/'};
|
||||
|
||||
/*
|
||||
* 运算符优先级表,与上面的OP表是呼应的。
|
||||
* 这里只有四则运算符号的优先级
|
||||
*/
|
||||
static const char PrecedeTable[7][7] = {
|
||||
{'>', '>', '<', '<'},
|
||||
{'>', '>', '<', '<'},
|
||||
{'>', '>', '>', '>'},
|
||||
{'>', '>', '>', '>'}
|
||||
};
|
||||
|
||||
/*
|
||||
* 根据给定的中缀表达式,返回其对应的逆波兰表达式(后缀表达式)
|
||||
* 如将"a+b*c-d/e"将转化为:"abc*+de/-"
|
||||
*
|
||||
*【注】
|
||||
* 表达式的变量为单字母,操作符只有'+'、'-'、'*'、'/'四则运算
|
||||
*/
|
||||
char* Algo_3_21(char s[]);
|
||||
|
||||
/*
|
||||
* 判断运算符栈中操作符o1与表达式中的操作符o2的优先级。
|
||||
*
|
||||
* 返回'>'、'<'、'=',以指示o1和o2的优先级
|
||||
*/
|
||||
char Precede(char o1, char o2);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* s = "a+b*c-d/e";
|
||||
|
||||
printf("中缀表达式为:");
|
||||
printf("%s\n", s);
|
||||
|
||||
printf("后缀表达式为:");
|
||||
printf("%s\n", Algo_3_21(s));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 根据给定的中缀表达式,返回其对应的逆波兰表达式(后缀表达式)
|
||||
* 如将"a+b*c-d/e"将转化为:"abc*+de/-"
|
||||
*
|
||||
*【注】
|
||||
* 表达式的变量为单字母,操作符只有'+'、'-'、'*'、'/'四则运算
|
||||
*/
|
||||
char* Algo_3_21(char s[]) {
|
||||
int i, j;
|
||||
SqStack S; // 运算符栈,临时存储操作符
|
||||
SElemType e; // SElemType被定义char类型,char和int类型可直接比较
|
||||
char* c;
|
||||
|
||||
// 逆波兰式序列
|
||||
c = (char*) malloc((strlen(s) + 1) * sizeof(char));
|
||||
|
||||
InitStack(&S);
|
||||
|
||||
for(i = j = 0; s[i] != '\0'; i++) {
|
||||
// 如果读到了字母,将其视为操作数,
|
||||
if(isalpha(s[i])) {
|
||||
c[j++] = s[i]; // 将字母直接存入逆波兰式中
|
||||
|
||||
// 如果读到的是运算符
|
||||
} else {
|
||||
while(!StackEmpty(S)) {
|
||||
// 获取栈顶元素
|
||||
GetTop(S, &e);
|
||||
|
||||
// 如果运算符栈中运算符优先级高
|
||||
if(Precede(e, s[i]) == '>') {
|
||||
Pop(&S, &e); // 将运算符栈中优先级高的操作符出栈
|
||||
c[j++] = e; // 将出栈后的操作符添加到逆波兰式中
|
||||
|
||||
// 如果遇到运算符栈中操作符优先级低时,结束循环
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 将表达式中读取到的操作符压入运算符栈
|
||||
Push(&S, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 将运算符栈中所有操作符追加到逆波兰式中
|
||||
while(!StackEmpty(S)) {
|
||||
Pop(&S, &e);
|
||||
c[j++] = e;
|
||||
}
|
||||
|
||||
// 数组中转换后的逆波兰式以"\0"标记结束
|
||||
c[j] = '\0';
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判断运算符栈中操作符o1与表达式中的操作符o2的优先级。
|
||||
*
|
||||
* 返回'>'、'<'、'=',以指示o1和o2的优先级
|
||||
*/
|
||||
char Precede(char o1, char o2) {
|
||||
int x, y;
|
||||
|
||||
// 获取指定的运算符在运算符表中的位置
|
||||
char* p1 = strchr(OP, o1);
|
||||
char* p2 = strchr(OP, o2);
|
||||
|
||||
// 计算出一个运算符优先级表坐标
|
||||
x = p1 - OP;
|
||||
y = p2 - OP;
|
||||
|
||||
return PrecedeTable[x][y];
|
||||
}
|
||||
7
CLion/ExerciseBook/03.21/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.21/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.21 SqStack.h SqStack.c 03.21.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.21 Scanf_lib)
|
||||
106
CLion/ExerciseBook/03.21/SqStack.c
Normal file
106
CLion/ExerciseBook/03.21/SqStack.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S) {
|
||||
if(S.top == S.base) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 取值
|
||||
*
|
||||
* 返回栈顶元素,并用e接收。
|
||||
*/
|
||||
Status GetTop(SqStack S, SElemType* e) {
|
||||
if(S.base == NULL || S.top == S.base) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 不会改变栈中元素
|
||||
*e = *(S.top - 1);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 栈满时,追加存储空间
|
||||
if((*S).top - (*S).base >= (*S).stacksize) {
|
||||
(*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW); // 存储分配失败
|
||||
}
|
||||
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
// 进栈先赋值,栈顶指针再自增
|
||||
*(S->top++) = e;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if((*S).top == (*S).base) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 出栈栈顶指针先递减,再赋值
|
||||
*e = *(--(*S).top);
|
||||
|
||||
return OK;
|
||||
}
|
||||
66
CLion/ExerciseBook/03.21/SqStack.h
Normal file
66
CLion/ExerciseBook/03.21/SqStack.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#ifndef SQSTACK_H
|
||||
#define SQSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量
|
||||
|
||||
/* 顺序栈元素类型定义 */
|
||||
typedef int SElemType;
|
||||
|
||||
// 顺序栈元素结构
|
||||
typedef struct {
|
||||
SElemType* base; // 栈底指针
|
||||
SElemType* top; // 栈顶指针
|
||||
int stacksize; // 当前已分配的存储空间,以元素为单位
|
||||
} SqStack;
|
||||
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S);
|
||||
|
||||
/*
|
||||
* 取值
|
||||
*
|
||||
* 返回栈顶元素,并用e接收。
|
||||
*/
|
||||
Status GetTop(SqStack S, SElemType* e);
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e);
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e);
|
||||
|
||||
#endif
|
||||
86
CLion/ExerciseBook/03.22/03.22.c
Normal file
86
CLion/ExerciseBook/03.22/03.22.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h> // 提供isdigit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 对逆波兰表达式求值(理论上要求操作数与运算结果均为个位数)
|
||||
*
|
||||
*【注】
|
||||
* 表达式的变量为单字母,操作符只有'+'、'-'、'*'、'/'四则运算
|
||||
*/
|
||||
Status Algo_3_22(char c[], SElemType* Value);
|
||||
|
||||
/* 计算 a oper b 的值 */
|
||||
char Operate(char a, char oper, char b);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char c[] = "124*+93/-";
|
||||
SElemType value;
|
||||
|
||||
printf("已知逆波兰式为:");
|
||||
printf("%s\n", c);
|
||||
|
||||
Algo_3_22(c, &value);
|
||||
printf("逆波兰式的计算结果为:%d\n", value - 48);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 对逆波兰表达式求值(理论上要求操作数与运算结果均为个位数)
|
||||
*
|
||||
*【注】
|
||||
* 表达式的变量为单字母,操作符只有'+'、'-'、'*'、'/'四则运算
|
||||
*/
|
||||
Status Algo_3_22(char c[], SElemType* Value) {
|
||||
int i;
|
||||
SqStack S;
|
||||
SElemType a, b;
|
||||
|
||||
InitStack(&S);
|
||||
|
||||
for(i = 0; c[i]!='\0'; ++i) {
|
||||
// 如果遇到数字字符
|
||||
if(isdigit(c[i])) {
|
||||
Push(&S, c[i]);
|
||||
} else {
|
||||
// 先弹出来的在操作数后边
|
||||
Pop(&S, &b);
|
||||
Pop(&S, &a);
|
||||
Push(&S, Operate(a, c[i], b));
|
||||
}
|
||||
}
|
||||
|
||||
Pop(&S, Value);
|
||||
|
||||
if(!StackEmpty(S)) {
|
||||
return ERROR;
|
||||
} else {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* 计算 a oper b 的值 */
|
||||
char Operate(char a, char oper, char b) {
|
||||
char c;
|
||||
|
||||
switch(oper) {
|
||||
case '+':
|
||||
c = (a - 48) + (b - 48) + 48;
|
||||
break;
|
||||
case '-':
|
||||
c = (a - 48) - (b - 48) + 48;
|
||||
break;
|
||||
case '*':
|
||||
c = (a - 48) * (b - 48) + 48;
|
||||
break;
|
||||
case '/':
|
||||
c = (a - 48) / (b - 48) + 48;
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.22/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.22/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.22 SqStack.h SqStack.c 03.22.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.22 Scanf_lib)
|
||||
90
CLion/ExerciseBook/03.22/SqStack.c
Normal file
90
CLion/ExerciseBook/03.22/SqStack.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S) {
|
||||
if(S.top == S.base) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 栈满时,追加存储空间
|
||||
if((*S).top - (*S).base >= (*S).stacksize) {
|
||||
(*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW); // 存储分配失败
|
||||
}
|
||||
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
// 进栈先赋值,栈顶指针再自增
|
||||
*(S->top++) = e;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if((*S).top == (*S).base) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 出栈栈顶指针先递减,再赋值
|
||||
*e = *(--(*S).top);
|
||||
|
||||
return OK;
|
||||
}
|
||||
59
CLion/ExerciseBook/03.22/SqStack.h
Normal file
59
CLion/ExerciseBook/03.22/SqStack.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#ifndef SQSTACK_H
|
||||
#define SQSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量
|
||||
|
||||
/* 顺序栈元素类型定义 */
|
||||
typedef int SElemType;
|
||||
|
||||
// 顺序栈元素结构
|
||||
typedef struct {
|
||||
SElemType* base; // 栈底指针
|
||||
SElemType* top; // 栈顶指针
|
||||
int stacksize; // 当前已分配的存储空间,以元素为单位
|
||||
} SqStack;
|
||||
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S);
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e);
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e);
|
||||
|
||||
#endif
|
||||
109
CLion/ExerciseBook/03.23/03.23.c
Normal file
109
CLion/ExerciseBook/03.23/03.23.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include <string.h> // 提供strlen原型
|
||||
#include <ctype.h> // 提供isalpha原型
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 将后缀表达式(逆波兰式)转换为前缀表达式(波兰式)
|
||||
*
|
||||
*【注】
|
||||
* 表达式的变量为单字母,操作符只有'+'、'-'、'*'、'/'四则运算
|
||||
*/
|
||||
char* Algo_3_23(char* c);
|
||||
|
||||
// 将字符转换为字符串
|
||||
char* CharToStr(char c);
|
||||
|
||||
// 拼接字符串a和b,返回拼接后的字符串
|
||||
char* StrCat(char* a, char* b);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* s = "abc+*de/-";
|
||||
|
||||
printf("中缀表达式:%s\n", "a*(b+c)-d/e");
|
||||
|
||||
printf("后缀表达式:");
|
||||
printf("%s\n", s);
|
||||
|
||||
printf("前缀表达式:");
|
||||
printf("%s\n", Algo_3_23(s));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 将后缀表达式(逆波兰式)转换为前缀表达式(波兰式)
|
||||
*
|
||||
*【注】
|
||||
* 表达式的变量为单字母,操作符只有'+'、'-'、'*'、'/'四则运算
|
||||
*/
|
||||
char* Algo_3_23(char* c) {
|
||||
int i;
|
||||
char* s, * e1, * e2;
|
||||
SqStack S;
|
||||
|
||||
InitStack(&S);
|
||||
|
||||
for(i = 0; c[i] != '\0'; i++) {
|
||||
s = CharToStr(c[i]);
|
||||
|
||||
// 若c[i]为操作符(不是操作数),则栈中至少应当有两个元素
|
||||
if(!isalpha(c[i])) {
|
||||
if(Pop(&S, &e2) && Pop(&S, &e1)) {
|
||||
s = StrCat(s, StrCat(e1, e2));
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Push(&S, s);
|
||||
}
|
||||
|
||||
Pop(&S, &s);
|
||||
|
||||
if(StackEmpty(S)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 将字符转换为字符串
|
||||
char* CharToStr(char c) {
|
||||
char* s;
|
||||
|
||||
s = (char*) malloc(2 * sizeof(char));
|
||||
|
||||
s[0] = c;
|
||||
s[1] = '\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// 拼接字符串a和b,返回拼接后的字符串
|
||||
char* StrCat(char* a, char* b) {
|
||||
char* s;
|
||||
int i, j, alen, blen;
|
||||
|
||||
alen = (int) strlen(a);
|
||||
blen = (int) strlen(b);
|
||||
|
||||
s = (char*) malloc((alen + blen + 1) * sizeof(char));
|
||||
|
||||
j = 0;
|
||||
|
||||
for(i = 0; i < alen; i++) {
|
||||
s[j++] = a[i];
|
||||
}
|
||||
|
||||
for(i = 0; i < blen; i++) {
|
||||
s[j++] = b[i];
|
||||
}
|
||||
|
||||
s[j] = '\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.23/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.23/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.23 SqStack.h SqStack.c 03.23.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.23 Scanf_lib)
|
||||
90
CLion/ExerciseBook/03.23/SqStack.c
Normal file
90
CLion/ExerciseBook/03.23/SqStack.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S) {
|
||||
if(S == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*S).top = (*S).base;
|
||||
(*S).stacksize = STACK_INIT_SIZE;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S) {
|
||||
if(S.top == S.base) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 栈满时,追加存储空间
|
||||
if((*S).top - (*S).base >= (*S).stacksize) {
|
||||
(*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
|
||||
if((*S).base == NULL) {
|
||||
exit(OVERFLOW); // 存储分配失败
|
||||
}
|
||||
|
||||
(*S).top = (*S).base + (*S).stacksize;
|
||||
(*S).stacksize += STACKINCREMENT;
|
||||
}
|
||||
|
||||
// 进栈先赋值,栈顶指针再自增
|
||||
*(S->top++) = e;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e) {
|
||||
if(S == NULL || (*S).base == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if((*S).top == (*S).base) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 出栈栈顶指针先递减,再赋值
|
||||
*e = *(--(*S).top);
|
||||
|
||||
return OK;
|
||||
}
|
||||
64
CLion/ExerciseBook/03.23/SqStack.h
Normal file
64
CLion/ExerciseBook/03.23/SqStack.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*=========================
|
||||
* 栈的顺序存储结构(顺序栈)
|
||||
==========================*/
|
||||
|
||||
#ifndef SQSTACK_H
|
||||
#define SQSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量
|
||||
#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量
|
||||
|
||||
/*
|
||||
* 顺序栈元素类型定义
|
||||
*
|
||||
*【注】
|
||||
* 这里使用字符串类型,即SElemType指向一个字符串
|
||||
*/
|
||||
typedef char* SElemType;
|
||||
|
||||
// 顺序栈元素结构
|
||||
typedef struct {
|
||||
SElemType* base; // 栈底指针
|
||||
SElemType* top; // 栈顶指针
|
||||
int stacksize; // 当前已分配的存储空间,以元素为单位
|
||||
} SqStack;
|
||||
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*
|
||||
* 构造一个空栈。初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitStack(SqStack* S);
|
||||
|
||||
/*
|
||||
* 判空
|
||||
*
|
||||
* 判断顺序栈中是否包含有效数据。
|
||||
*
|
||||
* 返回值:
|
||||
* TRUE : 顺序栈为空
|
||||
* FALSE: 顺序栈不为空
|
||||
*/
|
||||
Status StackEmpty(SqStack S);
|
||||
|
||||
/*
|
||||
* 入栈
|
||||
*
|
||||
* 将元素e压入到栈顶。
|
||||
*/
|
||||
Status Push(SqStack* S, SElemType e);
|
||||
|
||||
/*
|
||||
* 出栈
|
||||
*
|
||||
* 将栈顶元素弹出,并用e接收。
|
||||
*/
|
||||
Status Pop(SqStack* S, SElemType* e);
|
||||
|
||||
#endif
|
||||
36
CLion/ExerciseBook/03.24/03.24.c
Normal file
36
CLion/ExerciseBook/03.24/03.24.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/*
|
||||
* 递归计算g(m,n)
|
||||
*/
|
||||
int Algo_3_24(int m, int n);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int m, n;
|
||||
|
||||
m = 5;
|
||||
n = 2;
|
||||
|
||||
printf("g(%d,%d) = %d\n", m, n, Algo_3_24(m, n));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 递归计算g(m,n)
|
||||
*/
|
||||
int Algo_3_24(int m, int n) {
|
||||
if(m < 0 || n < 0) {
|
||||
exit(ERROR);
|
||||
}
|
||||
|
||||
if(m == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return Algo_3_24(m - 1, 2 * n) + n;
|
||||
}
|
||||
}
|
||||
7
CLion/ExerciseBook/03.24/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.24/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.24 03.24.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.24 Scanf_lib)
|
||||
67
CLion/ExerciseBook/03.25/03.25.c
Normal file
67
CLion/ExerciseBook/03.25/03.25.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/*
|
||||
* 方法1:递归法求解,优点是算法简单
|
||||
*
|
||||
* 递归计算F(n)
|
||||
*/
|
||||
int Algo_3_25_1(int n);
|
||||
|
||||
/*
|
||||
* 方法2:消除递归的迭代法,优点是存储了上一层计算数值
|
||||
*
|
||||
* 迭代计算F(n)
|
||||
*/
|
||||
int Algo_3_25_2(int n);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
printf("F(10) = %d\n", Algo_3_25_1(10));
|
||||
|
||||
printf("F(10) = %d\n", Algo_3_25_2(10));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 方法1:递归法求解,优点是算法简单
|
||||
*
|
||||
* 递归计算F(n)
|
||||
*/
|
||||
int Algo_3_25_1(int n) {
|
||||
if(n < 0) {
|
||||
exit(ERROR);
|
||||
}
|
||||
|
||||
if(n == 0) {
|
||||
return n + 1;
|
||||
} else {
|
||||
return n * Algo_3_25_1(n / 2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 方法2:消除递归的迭代法,优点是存储了上一层计算数值
|
||||
*
|
||||
* 迭代计算F(n)
|
||||
*/
|
||||
int Algo_3_25_2(int n) {
|
||||
int* a;
|
||||
int i;
|
||||
|
||||
if(n < 0) {
|
||||
exit(ERROR);
|
||||
}
|
||||
|
||||
a = (int*) malloc((n + 1) * sizeof(int));
|
||||
|
||||
for(i = 1, a[0] = 1; i <= n; i++) {
|
||||
a[i] = i * a[i / 2];
|
||||
}
|
||||
|
||||
return a[n];
|
||||
}
|
||||
7
CLion/ExerciseBook/03.25/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.25/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.25 03.25.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.25 Scanf_lib)
|
||||
62
CLion/ExerciseBook/03.26/03.26.c
Normal file
62
CLion/ExerciseBook/03.26/03.26.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/*
|
||||
* 方法1:递归法
|
||||
*
|
||||
* 递归计算平方根
|
||||
*/
|
||||
float Algo_3_26_1(float A, float p, float e);
|
||||
|
||||
/*
|
||||
* 方法2:迭代法
|
||||
*
|
||||
* 迭代计算平方根
|
||||
*/
|
||||
float Algo_3_26_2(float A, float p, float e);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
printf("√50 = %f\n", Algo_3_26_1(50, 1, 0.000001f));
|
||||
|
||||
printf("√50 = %f\n", Algo_3_26_2(50, 1, 0.000001f));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 方法1:递归法
|
||||
*
|
||||
* 递归计算平方根
|
||||
*/
|
||||
float Algo_3_26_1(float A, float p, float e) {
|
||||
if(A < 0.0) {
|
||||
exit(ERROR);
|
||||
}
|
||||
|
||||
if((p * p - A) > -e && (p * p - A) < e) {
|
||||
return p;
|
||||
} else {
|
||||
return Algo_3_26_1(A, (p + A / p) / 2, e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 方法2:迭代法
|
||||
*
|
||||
* 迭代计算平方根
|
||||
*/
|
||||
float Algo_3_26_2(float A, float p, float e) {
|
||||
if(A < 0.0) {
|
||||
exit(ERROR);
|
||||
}
|
||||
|
||||
while((p * p - A) >= e || (p * p - A) <= -e) {
|
||||
p = (p + A / p) / 2;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.26/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.26/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.26 03.26.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.26 Scanf_lib)
|
||||
105
CLion/ExerciseBook/03.27/03.27.c
Normal file
105
CLion/ExerciseBook/03.27/03.27.c
Normal file
@@ -0,0 +1,105 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 栈元素类型定义 */
|
||||
typedef struct {
|
||||
int mval;
|
||||
int nval;
|
||||
} SElemType;
|
||||
|
||||
/*
|
||||
* (1)递归法
|
||||
*
|
||||
* 递归计算阿克曼函数
|
||||
*/
|
||||
int Algo_3_27_1(int m, int n);
|
||||
|
||||
/*
|
||||
* (2)利用栈模拟递归
|
||||
*
|
||||
* 模拟栈计算阿克曼函数
|
||||
*/
|
||||
int Algo_3_27_2(int m, int n);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
printf("akm(3,4) = %d\n", Algo_3_27_1(3, 4));
|
||||
|
||||
printf("akm(3,4) = %d\n", Algo_3_27_2(3, 4));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (1)递归法
|
||||
*
|
||||
* 递归计算阿克曼函数
|
||||
*/
|
||||
int Algo_3_27_1(int m, int n) {
|
||||
int akm, tmp;
|
||||
|
||||
if(m < 0 || n < 0) {
|
||||
exit(ERROR);
|
||||
}
|
||||
|
||||
if(m == 0) {
|
||||
akm = n + 1;
|
||||
} else if(n == 0) {
|
||||
akm = Algo_3_27_1(m - 1, 1);
|
||||
} else {
|
||||
akm = Algo_3_27_1(m - 1, Algo_3_27_1(m, n - 1));
|
||||
}
|
||||
|
||||
return akm;
|
||||
}
|
||||
|
||||
/*
|
||||
* (2)利用栈模拟递归
|
||||
*
|
||||
* 模拟栈计算阿克曼函数
|
||||
*/
|
||||
int Algo_3_27_2(int m, int n) {
|
||||
SElemType stack[1000];
|
||||
int top = -1; // 初始化为-1,而不是0
|
||||
|
||||
if(m < 0 || n < 0) {
|
||||
exit(ERROR);
|
||||
}
|
||||
|
||||
// 先递增,再存值
|
||||
top++;
|
||||
|
||||
stack[top].mval = m;
|
||||
stack[top].nval = n;
|
||||
|
||||
while(1) {
|
||||
// m==0
|
||||
while(top>0 && stack[top].mval == 0) {
|
||||
top--;
|
||||
stack[top].mval = stack[top].mval - 1;
|
||||
stack[top].nval = stack[top + 1].nval + 1;
|
||||
}
|
||||
|
||||
if(top==0 && stack[0].mval == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// m!=0 n!=0
|
||||
while(stack[top].nval > 0) {
|
||||
top++;
|
||||
stack[top].mval = stack[top - 1].mval;
|
||||
stack[top].nval = stack[top - 1].nval - 1;
|
||||
}
|
||||
|
||||
// m!=0 n==0
|
||||
if(stack[top].nval == 0) {
|
||||
stack[top].mval = stack[top].mval - 1;
|
||||
stack[top].nval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return stack[top].nval + 1;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.27/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.27/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.27 03.27.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.27 Scanf_lib)
|
||||
157
CLion/ExerciseBook/03.28/03.28.c
Normal file
157
CLion/ExerciseBook/03.28/03.28.c
Normal file
@@ -0,0 +1,157 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include <limits.h> // 提供一些数值常量
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/*
|
||||
* ████ 注意 ████
|
||||
*
|
||||
* 这里使用带头结点的循环链表表示队列
|
||||
*/
|
||||
|
||||
/* 队列元素类型 */
|
||||
typedef int QElemType;
|
||||
|
||||
/* 队列结点类型 */
|
||||
typedef struct QNode {
|
||||
QElemType data;
|
||||
struct QNode* next;
|
||||
} QNode, * QueuePtr;
|
||||
|
||||
/* 队列结构 */
|
||||
typedef struct {
|
||||
QueuePtr rear; // 队尾指针
|
||||
} LinkQueue; // 队列的链式存储表示
|
||||
|
||||
// 队列初始化
|
||||
Status InitQueue_3_28(LinkQueue* Q);
|
||||
|
||||
// 入队
|
||||
Status EnQueue_3_28(LinkQueue* Q, QElemType e);
|
||||
|
||||
// 出队
|
||||
Status DeQueue_3_28(LinkQueue* Q, QElemType* e);
|
||||
|
||||
// 输出队列元素
|
||||
void Output(LinkQueue Q);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
LinkQueue Q;
|
||||
int i;
|
||||
QElemType e;
|
||||
|
||||
printf("████ 初始化队列...\n");
|
||||
InitQueue_3_28(&Q);
|
||||
|
||||
printf("████ 进行 5 次连续入队操作...\n");
|
||||
for(i = 1; i <= 5; i++) {
|
||||
EnQueue_3_28(&Q, i);
|
||||
|
||||
printf("█ 元素 \"%d\" 入队后,队列中的元素为:", i);
|
||||
Output(Q);
|
||||
}
|
||||
|
||||
printf("████ 进行 5 次连续出队操作...\n");
|
||||
for(i = 1; i <= 5; i++) {
|
||||
DeQueue_3_28(&Q, &e);
|
||||
|
||||
printf("█ 元素 \"%d\" 出队后,队列中的元素为:", e);
|
||||
Output(Q);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 队列初始化
|
||||
Status InitQueue_3_28(LinkQueue* Q) {
|
||||
if(Q == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 创建头结点
|
||||
(*Q).rear = (QueuePtr) malloc(sizeof(QNode));
|
||||
if((*Q).rear == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
// 头结点数据
|
||||
(*Q).rear->data = INT_MAX;
|
||||
|
||||
// 循环队列,首尾相接
|
||||
(*Q).rear->next = (*Q).rear;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 入队
|
||||
Status EnQueue_3_28(LinkQueue* Q, QElemType e) {
|
||||
QueuePtr p;
|
||||
|
||||
if(Q == NULL || (*Q).rear == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 创建新结点,链式队列被认为不存在队满的问题
|
||||
p = (QueuePtr) malloc(sizeof(QNode));
|
||||
if(p == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
p->data = e;
|
||||
|
||||
p->next = (*Q).rear->next;
|
||||
(*Q).rear->next = p;
|
||||
(*Q).rear = p;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 出队
|
||||
Status DeQueue_3_28(LinkQueue* Q, QElemType* e) {
|
||||
QueuePtr h, p;
|
||||
|
||||
if(Q == NULL || (*Q).rear == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 获取头结点
|
||||
h = (*Q).rear->next;
|
||||
|
||||
// 如果只有一个头结点,说明没有元素,无法队列
|
||||
if(h == (*Q).rear) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 指向待移除元素
|
||||
p = h->next;
|
||||
*e = p->data;
|
||||
|
||||
h->next = p->next;
|
||||
|
||||
// 如果只有一个元素
|
||||
if(p == (*Q).rear) {
|
||||
// 更新队尾游标
|
||||
(*Q).rear = h;
|
||||
}
|
||||
|
||||
free(p);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 输出队列元素
|
||||
void Output(LinkQueue Q) {
|
||||
QueuePtr p;
|
||||
|
||||
if(Q.rear == NULL) {
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(p = Q.rear->next->next; p != Q.rear->next; p = p->next) {
|
||||
printf("%d ", p->data);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
7
CLion/ExerciseBook/03.28/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.28/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.28 03.28.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.28 Scanf_lib)
|
||||
130
CLion/ExerciseBook/03.29/03.29.c
Normal file
130
CLion/ExerciseBook/03.29/03.29.c
Normal file
@@ -0,0 +1,130 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define MAXQSIZE 100 // 最大队列长度
|
||||
|
||||
/* 队列元素类型 */
|
||||
typedef int QElemType;
|
||||
|
||||
/* 顺序循环队列 */
|
||||
typedef struct {
|
||||
QElemType* base; // 指向队列存储空间
|
||||
int front, rear; // 队头和队尾游标
|
||||
int tag; // 0表示未满,1表示满
|
||||
} SqQueue;
|
||||
|
||||
// 队列初始化
|
||||
Status InitQueue_3_29(SqQueue* Q);
|
||||
|
||||
// 入队
|
||||
Status EnQueue_3_29(SqQueue* Q, QElemType e);
|
||||
|
||||
// 出队
|
||||
Status DeQueue_3_29(SqQueue* Q, QElemType* e);
|
||||
|
||||
// 输出队列元素
|
||||
void Output(SqQueue Q);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
SqQueue Q;
|
||||
int i;
|
||||
QElemType e;
|
||||
|
||||
printf("████ 初始化队列...\n");
|
||||
InitQueue_3_29(&Q);
|
||||
|
||||
printf("████ 进行 5 次连续入队操作...\n");
|
||||
for(i = 1; i <= 5; i++) {
|
||||
EnQueue_3_29(&Q, i);
|
||||
|
||||
printf("█ 元素 \"%d\" 入队后,队列中的元素为:", i);
|
||||
Output(Q);
|
||||
}
|
||||
|
||||
printf("████ 进行 5 次连续出队操作...\n");
|
||||
for(i = 1; i <= 5; i++) {
|
||||
DeQueue_3_29(&Q, &e);
|
||||
|
||||
printf("█ 元素 \"%d\" 出队后,队列中的元素为:", e);
|
||||
Output(Q);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 队列初始化
|
||||
Status InitQueue_3_29(SqQueue* Q) {
|
||||
if(Q == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*Q).base = (QElemType*) malloc(MAXQSIZE * sizeof(QElemType));
|
||||
if((*Q).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*Q).front = (*Q).rear = 0;
|
||||
(*Q).tag = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 入队
|
||||
Status EnQueue_3_29(SqQueue* Q, QElemType e) {
|
||||
// 队列满
|
||||
if((*Q).tag == 1) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*Q).base[(*Q).rear] = e;
|
||||
(*Q).rear = ((*Q).rear + 1) % MAXQSIZE;
|
||||
|
||||
// 如果发现队满,则更新标记
|
||||
if((*Q).rear == (*Q).front) {
|
||||
(*Q).tag = 1;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 出队
|
||||
Status DeQueue_3_29(SqQueue* Q, QElemType* e) {
|
||||
// 队列空
|
||||
if((*Q).front == (*Q).rear && (*Q).tag == 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
*e = (*Q).base[(*Q).front];
|
||||
(*Q).front = ((*Q).front + 1) % MAXQSIZE;
|
||||
|
||||
// 如果发现队空,则更新标记
|
||||
if((*Q).rear == (*Q).front) {
|
||||
(*Q).tag = 0;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 输出队列元素
|
||||
void Output(SqQueue Q) {
|
||||
int i;
|
||||
|
||||
// 队列空
|
||||
if(Q.front == Q.rear && Q.tag == 0) {
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
i = Q.front;
|
||||
|
||||
do {
|
||||
printf("%d ", Q.base[i]);
|
||||
i = (i + 1) % MAXQSIZE;
|
||||
} while(i != Q.rear);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
7
CLion/ExerciseBook/03.29/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.29/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.29 03.29.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.29 Scanf_lib)
|
||||
209
CLion/ExerciseBook/03.30+03.32/03.30+03.32.c
Normal file
209
CLion/ExerciseBook/03.30+03.32/03.30+03.32.c
Normal file
@@ -0,0 +1,209 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
#include "SqList.h" //**▲02 线性表**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define MAXQSIZE 5 // 队列长度,同时也是后续斐波那契数列数列的维度
|
||||
#define MAX 100000
|
||||
|
||||
/* 队列元素类型 */
|
||||
typedef int QElemType;
|
||||
|
||||
/* 顺序循环队列 */
|
||||
typedef struct {
|
||||
QElemType* base; // 指向队列存储空间
|
||||
int rear; // 队尾游标
|
||||
int length; // 队列元素个数
|
||||
} SqQueue;
|
||||
|
||||
// 队列初始化
|
||||
Status InitQueue_3_30(SqQueue* Q);
|
||||
|
||||
// 入队
|
||||
Status EnQueue_3_30(SqQueue* Q, QElemType e);
|
||||
|
||||
// 出队
|
||||
Status DeQueue_3_30(SqQueue* Q, QElemType* e);
|
||||
|
||||
/*
|
||||
* 求k阶斐波那契数列满足特定条件的前n+1项
|
||||
*/
|
||||
Status Algo_3_32(int k, SqList* fib);
|
||||
|
||||
|
||||
// 输出队列元素
|
||||
void Output(SqQueue Q) {
|
||||
int head;
|
||||
|
||||
if(Q.length == 0) {
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 队头游标
|
||||
head = (Q.rear - Q.length + MAXQSIZE) % MAXQSIZE;
|
||||
|
||||
do {
|
||||
printf("%d ", Q.base[head]);
|
||||
head = (head + 1) % MAXQSIZE;
|
||||
} while(head != Q.rear);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int i;
|
||||
|
||||
printf("████████ 题 3.30 验证...\n");
|
||||
{
|
||||
SqQueue Q;
|
||||
QElemType e;
|
||||
printf("████ 初始化队列...\n");
|
||||
InitQueue_3_30(&Q);\
|
||||
|
||||
printf("████ 进行 5 次连续入队操作...\n");
|
||||
for(i = 1; i <= 5; i++) {
|
||||
EnQueue_3_30(&Q, i);
|
||||
printf("█ 元素 \"%d\" 入队后,队列中的元素为:", i);
|
||||
Output(Q);
|
||||
}
|
||||
|
||||
printf("████ 进行 5 次连续出队操作...\n");
|
||||
for(i = 1; i <= 5; i++) {
|
||||
DeQueue_3_30(&Q, &e);
|
||||
printf("█ 元素 \"%d\" 出队后,队列中的元素为:", e);
|
||||
Output(Q);
|
||||
}
|
||||
}
|
||||
|
||||
printf("████████ 题 3.32 验证...\n");
|
||||
{
|
||||
SqList fib;
|
||||
|
||||
Algo_3_32(MAXQSIZE, &fib);
|
||||
printf("█ %d 阶斐波那契数列的前 %d 项为:\n", MAXQSIZE, fib.length);
|
||||
for(i = 0; i < fib.length; i++) {
|
||||
printf("%d ", fib.elem[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 队列初始化
|
||||
Status InitQueue_3_30(SqQueue* Q) {
|
||||
if(Q == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*Q).base = (QElemType*) malloc(MAXQSIZE * sizeof(QElemType));
|
||||
if((*Q).base == NULL) {
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*Q).rear = 0;
|
||||
(*Q).length = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 入队
|
||||
Status EnQueue_3_30(SqQueue* Q, QElemType e) {
|
||||
|
||||
if(Q == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 注意队列满的条件
|
||||
if((*Q).length == MAXQSIZE) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
(*Q).base[(*Q).rear] = e;
|
||||
(*Q).rear = ((*Q).rear + 1) % MAXQSIZE;
|
||||
|
||||
(*Q).length++;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 出队
|
||||
Status DeQueue_3_30(SqQueue* Q, QElemType* e) {
|
||||
int head;
|
||||
|
||||
if(Q == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 队列空
|
||||
if((*Q).length == 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 队头游标
|
||||
head = ((*Q).rear - (*Q).length + MAXQSIZE) % MAXQSIZE;
|
||||
|
||||
*e = (*Q).base[head];
|
||||
|
||||
(*Q).length--;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 求k阶斐波那契数列满足特定条件的前n+1项
|
||||
*
|
||||
*【注】
|
||||
* 个人感觉这个题出的有些牵强。
|
||||
* 因为既然要求计算前n+1项,但队列只保留后k项,这说明那个前n+1项必定需要保存到别的地方。
|
||||
* 可是,既然保存了前n+1项,就没必要用到循环队列中的后k项了,多余...
|
||||
* 如果本题改为计算满足条件的【第】n+1项的值,那么循环队列是有应用价值的
|
||||
*/
|
||||
Status Algo_3_32(int k, SqList* fib) {
|
||||
int flag;
|
||||
int i, j, sum;
|
||||
SqQueue Q;
|
||||
ElemType e;
|
||||
|
||||
if(k < 2 || MAX < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
InitQueue_3_30(&Q);
|
||||
InitList(fib);
|
||||
|
||||
// 前k-1项为0
|
||||
for(i = 1; i <= k - 1; i++) {
|
||||
EnQueue_3_30(&Q, 0);
|
||||
ListInsert(fib, i, 0);
|
||||
}
|
||||
|
||||
// 第k项为1
|
||||
EnQueue_3_30(&Q, 1);
|
||||
ListInsert(fib, i, 1);
|
||||
|
||||
while((flag = GetElem(*fib, i, &e))==OK && e<=MAX){
|
||||
/*
|
||||
* 计算循环队列中现有元素的和
|
||||
* 其实这一步可以改为计算顺序表中后k项的和,这样一来就没循环队列啥事了
|
||||
*/
|
||||
for(j = 0, sum = 0; j < Q.length; j++) {
|
||||
sum += Q.base[j];
|
||||
}
|
||||
|
||||
// 此处的e只是用作临时变量
|
||||
DeQueue_3_30(&Q, &e);
|
||||
|
||||
// 将新计算出的元素入队
|
||||
EnQueue_3_30(&Q, sum);
|
||||
|
||||
// 顺便往顺序表中缓存一份
|
||||
ListInsert(fib, ++i, sum);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.30+03.32/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.30+03.32/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.30+03.32 SqList.h SqList.c 03.30+03.32.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.30+03.32 Scanf_lib)
|
||||
105
CLion/ExerciseBook/03.30+03.32/SqList.c
Normal file
105
CLion/ExerciseBook/03.30+03.32/SqList.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*=============================
|
||||
* 线性表的顺序存储结构(顺序表)
|
||||
*
|
||||
* 包含算法: 2.3、2.4、2.5、2.6
|
||||
=============================*/
|
||||
|
||||
#include "SqList.h"
|
||||
|
||||
/*
|
||||
* ████████ 算法2.3 ████████
|
||||
*
|
||||
* 初始化
|
||||
*
|
||||
* 初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitList(SqList* L) {
|
||||
// 分配指定容量的内存,如果分配失败,则返回NULL
|
||||
(*L).elem = (ElemType*) malloc(LIST_INIT_SIZE * sizeof(ElemType));
|
||||
if((*L).elem == NULL) {
|
||||
// 存储内存失败
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
(*L).length = 0; // 初始化顺序表长度为0
|
||||
(*L).listsize = LIST_INIT_SIZE; // 顺序表初始内存分配量
|
||||
|
||||
return OK; // 初始化成功
|
||||
}
|
||||
|
||||
/*
|
||||
* 取值
|
||||
*
|
||||
* 获取顺序表中第i个元素,将其存储到e中。
|
||||
* 如果可以找到,返回OK,否则,返回ERROR。
|
||||
*
|
||||
*【备注】
|
||||
* 教材中i的含义是元素位置,从1开始计数,但这不符合编码的通用约定。
|
||||
* 通常,i的含义应该指索引,即从0开始计数。
|
||||
*/
|
||||
Status GetElem(SqList L, int i, ElemType* e) {
|
||||
// 因为i的含义是位置,所以其合法范围是:[1, length]
|
||||
if(i < 1 || i > L.length) {
|
||||
return ERROR; //i值不合法
|
||||
}
|
||||
|
||||
*e = L.elem[i - 1];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ████████ 算法2.4 ████████
|
||||
*
|
||||
* 插入
|
||||
*
|
||||
* 向顺序表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。
|
||||
*
|
||||
*【备注】
|
||||
* 教材中i的含义是元素位置,从1开始计数
|
||||
*/
|
||||
Status ListInsert(SqList* L, int i, ElemType e) {
|
||||
ElemType* newbase;
|
||||
ElemType* p, * q;
|
||||
|
||||
// 确保顺序表结构存在
|
||||
if(L == NULL || (*L).elem == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// i值越界
|
||||
if(i < 1 || i > (*L).length + 1) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// 若存储空间已满,则增加新空间
|
||||
if((*L).length >= (*L).listsize) {
|
||||
// 基于现有空间扩容
|
||||
newbase = (ElemType*) realloc((*L).elem, ((*L).listsize + LISTINCREMENT) * sizeof(ElemType));
|
||||
if(newbase == NULL) {
|
||||
// 存储内存失败
|
||||
exit(OVERFLOW);
|
||||
}
|
||||
|
||||
// 新基址
|
||||
(*L).elem = newbase;
|
||||
// 存的存储空间
|
||||
(*L).listsize += LISTINCREMENT;
|
||||
}
|
||||
|
||||
// q为插入位置
|
||||
q = &(*L).elem[i - 1];
|
||||
|
||||
// 1.右移元素,腾出位置
|
||||
for(p = &(*L).elem[(*L).length - 1]; p >= q; --p) {
|
||||
*(p + 1) = *p;
|
||||
}
|
||||
|
||||
// 2.插入e
|
||||
*q = e;
|
||||
|
||||
// 3.表长增1
|
||||
(*L).length++;
|
||||
|
||||
return OK;
|
||||
}
|
||||
66
CLion/ExerciseBook/03.30+03.32/SqList.h
Normal file
66
CLion/ExerciseBook/03.30+03.32/SqList.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*=============================
|
||||
* 线性表的顺序存储结构(顺序表)
|
||||
*
|
||||
* 包含算法: 2.3、2.4、2.5、2.6
|
||||
=============================*/
|
||||
|
||||
#ifndef SQLIST_H
|
||||
#define SQLIST_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // 提供malloc、realloc、free、exit原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
|
||||
/* 宏定义 */
|
||||
#define LIST_INIT_SIZE 100 // 顺序表存储空间的初始分配量
|
||||
#define LISTINCREMENT 10 // 顺序表存储空间的分配增量
|
||||
|
||||
/* 顺序表元素类型定义,跟队列元素类型一致 */
|
||||
typedef int ElemType;
|
||||
|
||||
/*
|
||||
* 顺序表结构
|
||||
*
|
||||
* 注:elem在使用前需要先为其分配内存,且元素从elem[0]处开始存储
|
||||
*/
|
||||
typedef struct {
|
||||
ElemType* elem; // 顺序表存储空间的基址(指向顺序表所占内存的起始位置)
|
||||
int length; // 当前顺序表长度(包含多少元素)
|
||||
int listsize; // 当前分配的存储容量(可以存储多少元素)
|
||||
} SqList;
|
||||
|
||||
|
||||
/*
|
||||
* ████████ 算法2.3 ████████
|
||||
*
|
||||
* 初始化
|
||||
*
|
||||
* 初始化成功则返回OK,否则返回ERROR。
|
||||
*/
|
||||
Status InitList(SqList* L);
|
||||
|
||||
/*
|
||||
* 取值
|
||||
*
|
||||
* 获取顺序表中第i个元素,将其存储到e中。
|
||||
* 如果可以找到,返回OK,否则,返回ERROR。
|
||||
*
|
||||
*【备注】
|
||||
* 教材中i的含义是元素位置,从1开始计数,但这不符合编码的通用约定。
|
||||
* 通常,i的含义应该指索引,即从0开始计数。
|
||||
*/
|
||||
Status GetElem(SqList L, int i, ElemType* e);
|
||||
|
||||
/*
|
||||
* ████████ 算法2.4 ████████
|
||||
*
|
||||
* 插入
|
||||
*
|
||||
* 向顺序表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。
|
||||
*
|
||||
*【备注】
|
||||
* 教材中i的含义是元素位置,从1开始计数
|
||||
*/
|
||||
Status ListInsert(SqList* L, int i, ElemType e);
|
||||
|
||||
#endif
|
||||
89
CLion/ExerciseBook/03.31/03.31.c
Normal file
89
CLion/ExerciseBook/03.31/03.31.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h> // 提供strlen函数的原型
|
||||
#include "Status.h" //**▲01 绪论**//
|
||||
#include "SqStack.h" //**▲03 栈和队列**//
|
||||
|
||||
/*
|
||||
* 判断序列s是否为回文序列
|
||||
* 空串也被视为回文序列
|
||||
*/
|
||||
Status Algo_3_31(char* s);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* a = "abcdedcba@";
|
||||
char* b = "ababab@";
|
||||
|
||||
if(Algo_3_31(a)) {
|
||||
printf("%s(不包括@)是回文序列!\n", a);
|
||||
} else {
|
||||
printf("%s(不包括@)不是回文序列!!\n", a);
|
||||
}
|
||||
|
||||
if(Algo_3_31(b)) {
|
||||
printf("%s(不包括@)是回文序列!\n", b);
|
||||
} else {
|
||||
printf("%s(不包括@)不是回文序列!!\n", b);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 判断序列s是否为回文序列
|
||||
* 空串也被视为回文序列
|
||||
*/
|
||||
Status Algo_3_31(char* s) {
|
||||
int len;
|
||||
int i;
|
||||
int m, n; // 回文串前半段的结尾下标和后半段的开始下标
|
||||
SqStack S;
|
||||
SElemType e;
|
||||
|
||||
len = (int) strlen(s);
|
||||
|
||||
if(len == 0 || s[len - 1] != '@') {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 空串被认为是回文序列
|
||||
if(len == 1) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(len % 2 == 0) {
|
||||
m = (len - 2) / 2 - 1;
|
||||
n = m + 2;
|
||||
} else {
|
||||
m = (len - 2) / 2;
|
||||
n = m + 1;
|
||||
}
|
||||
|
||||
InitStack(&S);
|
||||
|
||||
// 先把回文串前半段入栈
|
||||
for(i = 0; i <= m; i++) {
|
||||
Push(&S, s[i]);
|
||||
}
|
||||
|
||||
// 取出回文串前半段,与字符串序列后半段比对
|
||||
for(i = n; i <= len - 2; i++) {
|
||||
if(!StackEmpty(S)) {
|
||||
Pop(&S, &e);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if(s[i] != e) {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// 完美的状态应该是栈正好为空,且i为len-1
|
||||
if(!(StackEmpty(S) && i == len - 1)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
7
CLion/ExerciseBook/03.31/CMakeLists.txt
Normal file
7
CLion/ExerciseBook/03.31/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# 包含公共库
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Status)
|
||||
|
||||
# 生成可执行文件
|
||||
add_executable(03.31 SqStack.h SqStack.c 03.31.c)
|
||||
# 链接公共库
|
||||
target_link_libraries(03.31 Scanf_lib)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user