顺序栈和迷宫求解(C语言)

顺序栈

  根据《数据结构》书中的讲解,对顺序栈的一个基本实现。

define.h

 1 // define.h
 2 #ifndef __MENGQL_DEFINE__
 3 #define __MENGQL_DEFINE__
 4 
 5 #define C_LOG_DBG(format, ...) 
 6 //printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);
 7 #define C_LOG_ERR(format, ...) printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);
 8 typedef enum EStatus {ERROR, OK} Status;
 9 
10 #endif

SqStack.h

 1 // SqStack.h
 2 #ifndef __SQ_STACK_H__
 3 #define __SQ_STACK_H__
 4 #include "define.h"
 5 
 6 typedef struct
 7 {
 8     int x;
 9     int y;
10 }PosType;
11 
12 typedef struct
13 {
14     int ord;
15     PosType seat;
16     int di;
17 }SElemType;
18 
19 #define STACK_INIT_SIZE 100
20 typedef struct 
21 {
22     SElemType* base;
23     SElemType* top;
24     int stacksize;
25 }SqStack;
26 
27 extern Status InitStack(SqStack *S);
28 extern Status GetTopStack(SqStack S, SElemType *e);
29 extern Status PushStack(SqStack *S, SElemType e);
30 extern Status PopStack(SqStack *S, SElemType *e);
31 extern Status StackEmpty(SqStack *S);
32 extern Status DestoryStack(SqStack *S);
33 #endif

SqStack.c

 1 // SqStack.c
 2 #include "define.h"
 3 #include "SqStack.h"
 4 #include <stdlib.h>
 5 #include <stdio.h>
 6 Status InitStack(SqStack *S)
 7 {
 8     S->stacksize = STACK_INIT_SIZE;
 9     S->base = (SElemType *)malloc(S->stacksize * sizeof(SElemType));
10     if(S->base == NULL)
11     {
12         C_LOG_ERR("%s\n","MALLOC OVERFLOW!!!");
13         return ERROR;
14     }
15     S->top = S->base;
16     
17     return OK;
18 }
19 Status GetTopStack(SqStack S, SElemType *e)
20 {
21     if(S.top == S.base)
22     {
23         C_LOG_ERR("%s\n","STACK IS EMPTY!!!");
24         return ERROR;
25     }
26     *e = *(S.top-1);
27     return OK;
28 }
29 Status PushStack(SqStack *S, SElemType e)
30 {
31     if(S->top - S->base >= S->stacksize)
32     {
33         S->base = (SElemType *)realloc(S->base, (S->stacksize * 2) * sizeof(SElemType));
34         if(S->base == NULL)
35         {
36             C_LOG_ERR("%s\n","REMALLOC OVERFLOW!!!");
37             return ERROR;
38         }
39         S->stacksize *= 2;
40     }
41     *(S->top++) = e;
42     return OK;
43 }
44 Status PopStack(SqStack *S, SElemType *e)
45 {
46     if(S->top == S->base)
47     {
48         C_LOG_ERR("%s\n","STACK IS EMPTY!!!");
49         return ERROR;
50     }
51     *e = *(--S->top);
52     return OK;
53 }
54 Status StackEmpty(SqStack *S)
55 {
56     if(S->top == S->base)
57     {
58         return OK;
59     }
60     return ERROR;
61 }
62 Status DestoryStack(SqStack *S)
63 {
64     S->stacksize = 0;
65     free(S->base);
66     S->top = S->base = NULL;
67     return OK;
68 }

迷宫求解 

  顺序栈实现的迷宫求解是深度优先搜索,得出的路径是非最短路径。

测试用例 1
8 8
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0
0 1 1 1 1 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0 

Maze.c

//Maze.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "define.h"
#include "SqStack.h"


int **g_MazeMap;
int g_m, g_n;//g_m:列数 g_n:行数

#define FAILEDPOS 5
#define FOOTPRINT 2

void MazePrint()
{
    int i, j;
    for(i=0; i<g_m; ++i)
    {
        for(j=0; j<g_n; ++j)
        {
            printf("%d ", g_MazeMap[i][j]);
        }
        printf("\n");
    }
}

void MazePrintRes(SqStack *S)
{
    SElemType e;
    if(StackEmpty(S) == OK)
    {
        return;
    }
    else
    {
        PopStack(S, &e);
        MazePrintRes(S);
        printf("[%d][%d, %d]\n", e.ord, e.seat.x, e.seat.y);
    }
}

Status MazePass(PosType pos)
{
    if(pos.x>=0 && pos.y>=0 && pos.x<g_m && pos.y<g_n && g_MazeMap[pos.y][pos.x] == 0)
    {
        return OK;
    }
    return ERROR;
}
void MazeFootPrint(PosType pos)
{
    g_MazeMap[pos.y][pos.x] = FOOTPRINT;
}
void MarkPrint(PosType pos)
{
    g_MazeMap[pos.y][pos.x] = FAILEDPOS;
}
void NextPos(PosType *pos, int di)
{
    switch(di)
    {
        case 1:
            pos->y = pos->y-1;
            break;
        case 2:
            pos->x = pos->x-1;
            break;
        case 3:
            pos->y = pos->y+1;
            break;
        case 4:
            pos->x = pos->x+1;
            break;
        defult:
            break;
    }
}
/* 
DFS, use stack, is not shortest path
*/
Status MazePath(PosType *start, PosType *end)
{
    SqStack S;
    int nCurStep = 1;
    PosType curPos;
    SElemType e;
    
    curPos.x = start->x;
    curPos.y = start->y;
    if(InitStack(&S) != OK)
    {
        return ERROR;
    }
    do
    {
        if(MazePass(curPos) == OK)
        {
            MazeFootPrint(curPos);
            e.ord = nCurStep;
            e.di = 1;
            e.seat.x = curPos.x;
            e.seat.y = curPos.y;
            
            PushStack(&S, e);
            if(curPos.x == end->x && curPos.y == end->y)
            {
                MazePrintRes(&S);
                MazePrint();
                return OK;
            }
            NextPos(&curPos, e.di);
            nCurStep++;
        }
        else
        {
            if(StackEmpty(&S) != OK)
            {
                PopStack(&S, &e);
                C_LOG_DBG("[%d][%d][%d]\n", e.seat.x, e.seat.y, e.di);
                while(e.di>=4 && StackEmpty(&S)!=OK)
                {
                    MarkPrint(e.seat);
                    PopStack(&S, &e);
                    
                }
                C_LOG_DBG("[%d][%d][%d]\n", e.seat.x, e.seat.y, e.di);
                if(e.di < 4)
                {
                    e.di++;
                    PushStack(&S, e);
                    NextPos(&e.seat, e.di);
                    
                    curPos.x = e.seat.x;
                    curPos.y = e.seat.y;
                }
            }
        }
    }while(StackEmpty(&S) != OK);
    DestoryStack(&S);
    return ERROR;
}
/*
如果要输出最短路径,还需要进一步处理
*/
int main()
{
    PosType start;
    PosType end;
    int i, j;
    
    scanf("%d %d", &g_m, &g_n);
    start.x = 0;
    start.y = 0;
    end.x = g_m-1;
    end.y = g_n-1;
    
    g_MazeMap=(int**)malloc(g_m*sizeof(int*));
    for(i=0; i<g_m; ++i)
    {
        g_MazeMap[i] = (int*)malloc(g_n*sizeof(int));
    }
    
    for(i=0; i<g_m; ++i)
    {
        for(j=0; j<g_n; ++j)
        {
            scanf("%d", &g_MazeMap[i][j]);
        }
    }
    MazePath(&start, &end);
    return 0;
}

输出结果:

[1][0, 0]
[2][0, 1]
[3][0, 2]
[4][0, 3]
[5][0, 4]
[8][1, 4]
[9][2, 4]
[10][2, 5]
[11][3, 5]
[12][4, 5]
[13][4, 4]
[14][5, 4]
[15][5, 3]
[16][6, 3]
[17][6, 2]
[18][7, 2]
[21][7, 3]
[22][7, 4]
[23][6, 4]
[24][6, 5]
[25][7, 5]
[26][7, 6]
[27][7, 7]
2 0 1 0 0 0 1 5 
2 0 1 0 0 0 1 5 
2 0 0 0 1 1 2 2 
2 1 1 1 1 2 2 2 
2 2 2 1 2 2 2 2 
5 1 2 2 2 1 2 2 
5 1 1 1 0 1 1 2 
1 0 0 0 0 0 0 2 

  从结果可以看出,走了很多弯路。如果改用队列实现BFS就可以直接得出最短路径。

posted on 2012-08-22 11:47  favourmeng  阅读(1786)  评论(0编辑  收藏  举报

导航