16 - 12 - 21 栈的应用实例(走迷宫)

栈的应用举例————【一:数制转换】
需要不断的重复求余算法。
由于计算时是从低位到高位顺序产生二进制的各个数位。
而打印出时应从高位到低位进行。非常适合用栈来进行这个过程。

//N是待转数字,R是进制数。
//函数 1、
typedef int DataType;
void conversion(int N,int R)
{
    SeqStack s;
    DataType x;
    Init_SeqStack(&s);
    while(N){
        Push_SeqStack(&s,N%R);
        N = N/R;
    }
    while(!Empty_SeqStack(&s))
    {
        Pop_SeqStack(&s);
        printf("%d",x);  //循环输出。
    }
}

//函数 2、
#define L 10
void conversion(int N,int R)
{
    int S[L],top = -1 ,x ;
    while(N){
        s[++top] = N%R;
        N = N/R;
    }
    while(top != -1){
        x = s[top--]
        printf("%d\n",x);
    }
}

栈的应用举例————【二:走迷宫问题】
这里写图片描述

设迷宫为 m 行 n 列,利用maze[m][n] = 0 或 1 ;
其中 0表示通路,1 表示不通 。
当从某点向下试探时,中间点有八个方向,角点有两个
( 例外:起点有三个),边点有四个。
外围的一圈都是围墙,为了简化问题,我们用maze[m+2][n+2]来表示迷宫,(迷宫的四周都是 1 也就是墙 )。
然后还是为了简化,我们设定每个点的试探方向都是8,这样就不用再判断当前点是什么类型的点 ; move[8],将试探顺序规定为:从正东沿着顺时针方向运行。

0~7分别代表8个方向。
move 数组定义如下:

typedef struct{
    int x,y;   }item;
item move[8];

当到达了某点而无路可走时,需要返回到前一个点。再从前一个点开始向下一个方向继续试探,因此,压入栈中的不仅是顺序到达的各点的坐标,而且还要有从前一点到达本点的方向。如图:

后面0,1,2,3代表方向。看迷宫 ↑

栈元素的设计如下:

typedef struct{
int x,y,d;
}mazestack ;    

如何防止重复到达某点呢?一种方法是设置一个标志数组,maze[m][n],将,maze中的所有元素置 0 ,一旦到达了某点
(i,j)后,maze[i][j]为-1,下次再判断到这个位置,就不能走了。
迷宫求解的算法思想如下(好好看!!)

int maze[m][n];
item move[8];
SeqStack s;  //顺序栈
mazestack temp;
int x,y,d,i,j;
temp.x = 1,temp.y = 1,temp.d = -1;
Push_SeqStack(&s,temp);
while(!Empty_SeqStack(&s)) {
    Pop_SeqStack(&s,&temp);
    x = temp.x ;
    y = temp.y;
    d = temp.d + 1;
    while(d<8) {
        i = x + move[d].x;
        j = y + move[d].y;
        if(maze[i][j] == 0) {
            temp = {x,y,d};
            Push_SeqStack(&s,temp);
            x = i ;
            y = j ;
            maze[x][y] = -1;
            if(x==m && n==n)
                return 1;
            else
                d = 0;
        } else
            d++;   /*while ( d < 8 ) */
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值