本文是對順序棧的兩個簡單應用(數制轉換、迷宮求解)進行練習。代碼如下所示:
#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;
}