数据结构算法C语言实现--- 3.2栈的应用举例:迷宫求解与表达式求值
Posted 苟不利包子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构算法C语言实现--- 3.2栈的应用举例:迷宫求解与表达式求值相关的知识,希望对你有一定的参考价值。
一.简介
迷宫求解:类似图的DFS。具体的算法思路可以参考书上的50、51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意。大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩。这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求。
表达式求值:
由于数据的读入是按照字符读入的,所以这个简单的小程序只能计算个位数的运算。
二.头文件
迷宫求解:
1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:zhaoyu1995.com@gmail.com 5 date:2016-6-8 6 note:realize my textbook <<数据结构(C语言版)>> 7 */ 8 //Page 51 9 #ifndef _3_2_MAZE_H 10 #define _3_2_MAZE_H 11 #include <cstdio> 12 #include <cstdlib> 13 #include <cstring> 14 #include "head.h" 15 #define STACK_INIT_SIZE 200//存储空间的初始分配值 16 #define STACKINCREMENT 10//存储空间分配增量 17 #define WALL -1 18 #define PATH 1 19 #define PASSED -2 20 #define UNREACHABLE -3 21 #define FINALPATH -4 22 #define NMAX 50 23 char Map[NMAX][NMAX]; 24 typedef struct{ 25 int x; 26 int y; 27 }PosType; 28 typedef struct node_1{ 29 int x, y; 30 struct node_1 *next; 31 }MazeType; 32 typedef struct{ 33 int ord;//通道块在路径上的序号 34 PosType seat;//通道块在迷宫中的位置 35 int direction;//从此通道块走向下一通道块的方向 36 }SElemType; 37 typedef struct{ 38 SElemType *base;//在栈构造之前和销毁之后,base 值为 NULL 39 SElemType *top;//栈顶指针 40 int stacksize;//当前已分配的存储空间,以元素为单位 41 }SqStack; 42 Status InitStack(SqStack &S) 43 { 44 //构造一个空栈 S 45 S.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); 46 if (!S.base) 47 { 48 exit(OVERFLOW); 49 } 50 S.top = S.base; 51 S.stacksize = STACK_INIT_SIZE; 52 return OK; 53 }//InitStack 54 void Assign_PosType(PosType &a, PosType b) 55 { 56 a.x = b.x; 57 a.y = b.y; 58 }//Assign_PosType 59 Status Pass(PosType pos) 60 {//可能写的不对,注意 61 if (PATH == Map[pos.x][pos.y]) 62 { 63 return TRUE; 64 } 65 else 66 { 67 return FALSE; 68 } 69 }//Pass 70 void FoorPrint(PosType pos) 71 { 72 Map[pos.x][pos.y] = PASSED; 73 } 74 void Assign_SELemType(SElemType &e, int x, PosType pos, int y) 75 { 76 e.ord = x; 77 Assign_PosType(e.seat, pos); 78 e.direction = y; 79 } 80 Status Push(SqStack &S, SElemType e) 81 { 82 //插入元素 e 为新的栈顶元素 83 if (S.top - S.base >= S.stacksize) 84 {//栈满,追加存储空间 85 S.base = (SElemType *)realloc(S.base, 86 (S.stacksize+STACKINCREMENT)*sizeof(SElemType)); 87 if (!S.base) 88 { 89 exit(OVERFLOW); 90 } 91 S.top = S.base + S.stacksize; 92 S.stacksize += STACKINCREMENT; 93 } 94 //*S.top++ = e; 95 Assign_SELemType(*S.top++, e.ord, e.seat, e.direction); 96 return OK; 97 }//Push 98 PosType NextPos(PosType pos, int direction) 99 { 100 PosType temp; 101 switch (direction) 102 { 103 case 1: 104 { 105 temp.x = pos.x; 106 temp.y = pos.y+1; 107 break; 108 } 109 case 2: 110 { 111 temp.x = pos.x + 1; 112 temp.y = pos.y; 113 break; 114 } 115 case 3: 116 { 117 temp.x = pos.x; 118 temp.y = pos.y - 1; 119 break; 120 } 121 case 4: 122 { 123 temp.x = pos.x - 1; 124 temp.y = pos.y; 125 break; 126 } 127 } 128 //加一个越界检查 129 return temp; 130 } 131 Status StackEmpty(SqStack S) 132 { 133 //若 S 为空栈, 则返回 TRUE, 否则返回 FALSE 134 if (S.base == S.top) 135 { 136 return TRUE; 137 } 138 else 139 { 140 return FALSE; 141 } 142 } 143 Status Pop(SqStack &S, SElemType &e) 144 { 145 //若栈不空,则删除 S 的栈顶元素,用 e 返回其 146 //值,并返回OK;否则返回ERROR 147 if (S.top == S.base) 148 { 149 return ERROR; 150 } 151 //e = *--S.top; 152 S.top--; 153 Assign_SELemType(e, (*S.top).ord, (*S.top).seat, (*S.top).direction); 154 return OK; 155 }//Pop 156 void FootPrint(PosType pos) 157 { 158 Map[pos.x][pos.y] = PASSED; 159 } 160 void MarkPrint(PosType pos) 161 { 162 Map[pos.x][pos.y] = UNREACHABLE; 163 } 164 void MakeMap(int size) 165 { 166 memset(Map, 0, sizeof(Map)); 167 char ch; 168 getchar(); 169 for (int i = 1; i <= size; i++) 170 { 171 for (int j = 1; j <= size; j++) 172 { 173 scanf("%c", &ch); 174 if (\'X\' == ch) 175 { 176 Map[i][j] = UNREACHABLE; 177 } 178 else 179 { 180 Map[i][j] = PATH; 181 } 182 } 183 //attention \'\\n\' 184 getchar(); 185 } 186 //Print maze 187 for (int i = 1; i <= size; i++) 188 { 189 for (int j = 1; j <= size; j++) 190 { 191 if (UNREACHABLE == Map[i][j]) 192 { 193 printf("X"); 194 } 195 else 196 { 197 printf(" "); 198 } 199 } 200 printf("\\n"); 201 } 202 } 203 void PrintPath(SqStack S, int size) 204 { 205 SElemType e; 206 SqStack temp; 207 while (!StackEmpty(S)) 208 { 209 Pop(S, e); 210 Map[e.seat.x][e.seat.y] = FINALPATH; 211 } 212 for (int i = 1; i <= size; i++) 213 { 214 for (int j = 1; j <= size; j++) 215 { 216 if (UNREACHABLE == Map[i][j]) 217 { 218 printf("X"); 219 } 220 else if (FINALPATH == Map[i][j]) 221 { 222 printf("O"); 223 } 224 else 225 { 226 printf(" "); 227 } 228 } 229 printf("\\n"); 230 } 231 } 232 Status MazePath(MazeType maze, PosType start, PosType end, int size) 233 { 234 //若迷宫 maze 中存在从入口 start 到出口 end 的通道, 235 //则求得一条存放在栈中(从栈底到栈顶),并返回 TRUE, 236 //否则返回 FALSE 237 SqStack S; 238 InitStack(S); 239 //curpos = start 240 PosType curpos; 241 Assign_PosType(curpos, start);//设定当前位置为入口位置 242 int curstep = 1;//探索第一步 243 SElemType e; 244 do{ 245 if (TRUE == Pass(curpos)) 246 {//当前位置可以通过 247 FootPrint(curpos);//留下足迹 248 //e = (curstep, curpos, 1); 249 Assign_SELemType(e, curstep, curpos, 1); 250 Push(S, e);//加入路径 251 if (curpos.x == end.x && curpos.y == end.y) 252 { 253 //打印路径 254 printf("PATH EXIST\\n"); 255 PrintPath(S ,size); 256 return TRUE; 257 } 258 curpos = NextPos(curpos, 1);//下一位置是当前位置的东邻 259 curstep++;//探索下一步 260 } 261 else 262 { 263 if (!StackEmpty(S)) 264 { 265 Pop(S, e); 266 while (4 == e.direction && !StackEmpty(S)) 267 { 268 MarkPrint(e.seat); 269 Pop(S, e);//留下不能通过的标记,并退回一步 270 } 271 if (e.direction < 4) 272 { 273 e.direction++; 274 Push(S, e); 275 curpos = NextPos(e.seat, e.direction); 276 } 277 } 278 } 279 }while (!StackEmpty(S)); 280 281 } 282 #endif
表达式求值:
1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:zhaoyu1995.com@gmail.com 5 date:2016-6-8 6 note:realize my textbook <<数据结构(C语言版)>> 7 */ 8 //Page 53 9 #ifndef _3_2_EXPRESSION_H_ 10 #define _3_2_EXPRESSION_H_ 11 #include "head.h" 12 13 #define SElemType char 14 #define OperandType float 15 #define STACK_INIT_SIZE 100//存储空间的初始分配值 16 #define STACKINCREMENT 10//存储空间分配增量 17 typedef struct{ 18 SElemType *base;//在栈构造之前和销毁之后,base 值为 NULL 19 SElemType *top;//栈顶指针 20 int stacksize;//当前已分配的存储空间,以元素为单位 21 }SqStack_Char; 22 typedef struct{ 23 OperandType *base;//在栈构造之前和销毁之后,base 值为 NULL 24 OperandType *top;//栈顶指针 25 int stacksize;//当前已分配的存储空间,以元素为单位 26 }SqStack_Float; 27 Status InitStack_Char(SqStack_Char &S) 28 { 29 //构造一个空栈 S 30 S.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); 31 if (!S.base) 32 { 33 exit(OVERFLOW); 34 } 35 S.top = S.base; 36 S.stacksize = STACK_INIT_SIZE; 37 return OK; 38 }//InitStack 39 Status InitStack_Float(SqStack_Float &S) 40 { 41 //构造一个空栈 S 42 S.base = (OperandType *)malloc(STACK_INIT_SIZE*sizeof(OperandType)); 43 if (!S.base) 44 { 45 exit(OVERFLOW); 46 } 47 S.top = S.base; 48 S.stacksize = STACK_INIT_SIZE; 49 return OK; 50 }//InitStack 51 Status Push_Char(SqStack_Char &S, SElemType e) 52 { 53 //插入元素 e 为新的栈顶元素 54 if (S.top - S.base >= S.stacksize) 55 {//栈满,追加存储空间 56 S.base = (SElemType *)realloc(S.base, 57 (S.stacksize+STACKINCREMENT)*sizeof(SElemType)); 58 if (!S.base) 59 { 60 exit(OVERFLOW); 61 } 62 S.top = S.base + S.stacksize; 63 S.stacksize += STACKINCREMENT; 64 } 65 *S.top++ = e; 66 return OK; 67 }//Push 68 SElemType GetTop_Char(SqStack_Char S) 69 { 70 //若栈不空,则用 e 返回 S 的栈顶元素,并返回 OK; 71 //否则返回ERROR 72 if (S.top == S.base) 73 { 74 return ERROR; 75 } 76 return *(S.top - 1); 77 }//GetTop 78 Status isInOPTR(SElemType c) 79 { 80 switch (c) 81 { 82 case \'+\': 83 case \'-\': 84 case \'*\': 85 case \'/\': 86 case \'(\': 87 case \')\': 88 case \'#\': 89 { 90 return TRUE; 91 break; 92 } 93 default: 94 { 95 return FALSE; 96 break; 97 } 98 } 99 } 100 Status Push_Float(SqStack_Float &S, OperandType e) 101 { 102 //插入元素 e 为新的栈顶元素 103 if (S.top - S.base >= S.stacksize) 104 {//栈满,追加存储空间 105 S.base = (OperandType *)realloc(S.base, 106 (S.stacksize+STACKINCREMENT)*sizeof(OperandType)); 107 if (!S.base) 108 { 109 exit(OVERFLOW); 110 } 111 S.top = S.base + S.stacksize; 112 S.stacksize += STACKINCREMENT; 113 } 114 *S.top++ = e; 115 return OK; 116 }//Push 117 char Precede(SElemType a, SElemType b) 118 { 119 char R[7][7] = {{\'>\',\'>\',\'<\',\'<\',\'<\',\'&g以上是关于数据结构算法C语言实现--- 3.2栈的应用举例:迷宫求解与表达式求值的主要内容,如果未能解决你的问题,请参考以下文章