本文是对顺序栈的两个简单应用(数制转换、迷宫求解)进行练习。代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define STACK_INIT_SIZE 10
#define STACK_INCREMENT 10
// typedef int ElemType;
typedef struct {
int x; // 横坐标
int y; // 纵坐标
}POS;
typedef struct {
int sno; // 序号
POS seat; // 位置坐标
int di; // 方向
}ElemType;
typedef struct {
ElemType *base;
ElemType *top;
int size;
}STACK;
STACK *InitStack();
void DestoryStack(STACK *s);
int Push(STACK *s, ElemType *e);
int Pop(STACK *s, ElemType *e);
int IsEmpty(STACK *s);
// 应用一:数制转化
// int main()
// {
// int num = 1348, temp;
// STACK *stack = InitStack();
//
// while (num){
// temp = num % 8;
// Push(stack,&temp);
// num /= 8;
// }
//
// while (!IsEmpty(stack)){
// Pop(stack,&temp);
// printf("%d",temp);
// }
//
// DestoryStack(stack);
// return 0;
// }
static const POS inpos = {1,1}, outpos = {8,8}; // 起点为(1,1) 重点为(8,8)
int item[10][10] = { // 构造迷宫,可通为0,不通为1
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,0,0,1,1,0,0,1},
{1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,0,1},
{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1}
};
POS NextPos(POS curpos, int di)
{
POS p = curpos;
switch (di){
case 0:
p.x--;
break;
case 1:
p.y++;
break;
case 2:
p.x++;
break;
case 3:
p.y--;
break;
}
return p;
}
int Pass(POS curpos) // 判断是否可通
{
return item[curpos.y][curpos.x] == 0 ? 1 : 0;
}
void PrintItem(POS curpos)
{
int i, j;
system("cls"); // 清屏
for (i = 0; i < 10; ++i){
for (j = 0; j < 10; ++j){
if (curpos.y == i && curpos.x == j){
printf("@");
continue; // 不加continue; 试试
}
if (1 == item[i][j])
printf("*");
else
printf(" ");
}
printf("\n");
}
}
// 应用二:迷宫求解
int main()
{
STACK *s = InitStack();
ElemType e;
POS curpos = inpos; // 设定当前位置为入口位置
int step = 1; // 探索第一步
PrintItem(curpos);
do {
if (Pass(curpos)){ // 可通
e.sno = step;
e.seat = curpos;
e.di = 0;
Push(s,&e); // 将模块的位置压入栈
item[curpos.y][curpos.x] = 2; // 留下足迹
if (curpos.x == outpos.x && curpos.y == outpos.y){ // 如果已经是出口
printf("OK!\n");
break;
}
PrintItem(curpos);
getch(); // 暂停好观察模块的移动
curpos = NextPos(curpos, 0); // 下一位置是 左边
step++;
}
else
{
Pop(s,&e);
while (4 == e.di && (!IsEmpty(s))){
item[curpos.y][curpos.x] = 3; // 留下足迹
Pop(s,&e); // 退回一步
}
if (e.di < 4){ // 换下一方向
e.di++;
Push(s,&e);
curpos = NextPos(e.seat,e.di); // 设当前位置是新方向上的相邻块
}
}
} while (!IsEmpty(s));
return 0;
}
STACK *InitStack()
{
STACK *s = (STACK *)malloc(sizeof(STACK));
if (NULL == s)
exit(0);
s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if (NULL == s->base)
exit(0);
s->top = s->base;
s->size = STACK_INIT_SIZE;
return s;
}
void DestoryStack(STACK *s)
{
free(s->base);
free(s);
}
int Push(STACK *s, ElemType *e)
{
if (NULL == s || NULL == e)
return 0;
if (s->size == s->top - s->base){
s->base = (ElemType *)realloc(s->base, (s->size + STACK_INCREMENT) * sizeof(ElemType));
if (NULL == s->base)
return 0;
s->top = s->base + s->size;
s->size += STACK_INCREMENT;
}
// *s->top = *e;
// s->top++;
*s->top++ = *e;
return 1;
}
int Pop(STACK *s, ElemType *e)
{
if (NULL == s || NULL == e)
return 0;
if (IsEmpty(s))
return 0;
// s->top--;
// *e = *s->top;
*e = *--s->top;
return 1;
}
int IsEmpty(STACK *s)
{
return s->top == s->base ? 1 : 0;
}