迷宫最短路径(DFS)

  前面的《顺序栈和迷宫求解》中已经提到,用栈DFS的方法求得的路径是非最短路径。如果要求得最短路径需要进一步处理。

  1. 增加一个全局数组(PrintType **g_MazeFootPrint),用来存放到某个节点的最短路径长度(shorteststep)和到达该节点的上一个节点位置(parent)。

typedef struct
{
    PosType parent;
    int shorteststep;
}PrintType;
PrintType **g_MazeFootPrint;

  2. 修改“是否可走”的条件,即修改如下函数:

1 Status MazePass(PosType pos, int x, int y)
2 {
3     if(pos.x>=0 && pos.y>=0 && pos.x<g_m && pos.y<g_n 
4     && (g_MazeMap[pos.y][pos.x] == 0 || g_MazeFootPrint[y][x].shorteststep + 1 < g_MazeFootPrint[pos.y][pos.x].shorteststep))
5     {
6         return OK;
7     }
8     return ERROR;
9 }

  增加了一个判断条件,当到达目前节点的路径小于原有路径时,可重走此节点。同时修改到达当前节点的路径大小。

  3. 当找到出口时不立即返回,而继续搜索;

  代码如下:

 define.h

// define.h
#ifndef __MENGQL_DEFINE__
#define __MENGQL_DEFINE__

#define C_LOG_DBG(format, ...) 
//printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);
#define C_LOG_ERR(format, ...) printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);
typedef enum EStatus {ERROR, OK} Status;

#endif

 SqStack.h

// SqStack.h
#ifndef __SQ_STACK_H__
#define __SQ_STACK_H__
#include "define.h"

typedef struct
{
    int x;
    int y;
}PosType;

typedef struct
{
    PosType seat;
    int di;
}SElemType;

#define STACK_INIT_SIZE 100
typedef struct 
{
    SElemType* base;
    SElemType* top;
    int stacksize;
}SqStack;

extern Status InitStack(SqStack *S);
extern Status GetTopStack(SqStack S, SElemType *e);
extern Status PushStack(SqStack *S, SElemType e);
extern Status PopStack(SqStack *S, SElemType *e);
extern Status StackEmpty(SqStack *S);
extern Status DestoryStack(SqStack *S);
#endif

 MazeShortPath.c

  1 // MazeShortPath.c
  2 #include <string.h>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include "define.h"
  6 #include "SqStack.h"
  7 
  8 
  9 typedef struct
 10 {
 11     PosType parent;
 12     int shorteststep;
 13 }PrintType;
 14 
 15 PrintType **g_MazeFootPrint;
 16 int **g_MazeMap;
 17 int g_m, g_n;//g_m:列数 g_n:行数
 18 
 19 #define FAILEDPOS 5
 20 #define FOOTPRINT 2
 21 
 22 void MazePrintRes(PosType *start, PosType *end)
 23 {
 24     PosType p;
 25     if(end->x == start->x && end->y == start->y)
 26     {
 27         printf("[%d, %d]\n", start->x, start->y);
 28         return;
 29     }
 30     else
 31     {
 32         p.x = g_MazeFootPrint[end->y][end->x].parent.x;
 33         p.y = g_MazeFootPrint[end->y][end->x].parent.y;
 34         MazePrintRes(start, &p);
 35         printf("[%d, %d]\n", end->x, end->y);
 36         return;
 37     }
 38 }
 39 Status MazePass(PosType pos, int x, int y)
 40 {
 41     if(pos.x>=0 && pos.y>=0 && pos.x<g_m && pos.y<g_n 
 42     && (g_MazeMap[pos.y][pos.x] == 0 || g_MazeFootPrint[y][x].shorteststep + 1 < g_MazeFootPrint[pos.y][pos.x].shorteststep))
 43     {
 44         return OK;
 45     }
 46     return ERROR;
 47 }
 48 void MazeFootPrint(PosType pos)
 49 {
 50     g_MazeMap[pos.y][pos.x] = FOOTPRINT;
 51 }
 52 void MarkPrint(PosType pos)
 53 {
 54     g_MazeMap[pos.y][pos.x] = FAILEDPOS;
 55 }
 56 void NextPos(PosType *pos, int di)
 57 {
 58     switch(di)
 59     {
 60         case 1:
 61             pos->y = pos->y-1;
 62             break;
 63         case 2:
 64             pos->x = pos->x-1;
 65             break;
 66         case 3:
 67 
 68             pos->y = pos->y+1;
 69             break;
 70         case 4:
 71             pos->x = pos->x+1;
 72             break;
 73         defult:
 74             break;
 75     }
 76 }
 77 Status MazeShortPath(PosType *start, PosType *end)
 78 {
 79     SqStack S;
 80     int nCurStep = 0;
 81     PosType curPos;
 82     SElemType e;
 83     int nPrevX = 0;
 84     int nPrevY = 0;
 85     Status ERes = ERROR;
 86     
 87     curPos.x = start->x;
 88     curPos.y = start->y;
 89     if(InitStack(&S) != OK)
 90     {
 91         return ERROR;
 92     }
 93     do
 94     {
 95         if(MazePass(curPos, nPrevX, nPrevY) == OK)
 96         {
 97             g_MazeFootPrint[curPos.y][curPos.x].shorteststep = g_MazeFootPrint[nPrevY][nPrevX].shorteststep + 1;
 98             g_MazeFootPrint[curPos.y][curPos.x].parent.x = nPrevX;
 99             g_MazeFootPrint[curPos.y][curPos.x].parent.y = nPrevY;
100             
101             e.di = 1;
102             e.seat.x = curPos.x;
103             e.seat.y = curPos.y;
104             
105             MazeFootPrint(curPos);
106             PushStack(&S, e);
107             
108             if(curPos.x == end->x && curPos.y == end->y)
109             {
110                 ERes = OK;
111             }
112             nPrevX = e.seat.x;
113             nPrevY = e.seat.y;
114             NextPos(&curPos, e.di);
115         }
116         else
117         {
118             if(StackEmpty(&S) != OK)
119             {
120                 PopStack(&S, &e);
121                 while(e.di>=4 && StackEmpty(&S)!=OK)
122                 {
123                     MarkPrint(e.seat);
124                     PopStack(&S, &e);
125                     
126                 }
127                 if(e.di < 4)
128                 {
129                     e.di++;
130                     PushStack(&S, e);
131                     nPrevX = e.seat.x;
132                     nPrevY = e.seat.y;
133                     NextPos(&e.seat, e.di);
134                     
135                     curPos.x = e.seat.x;
136                     curPos.y = e.seat.y;
137                 }
138             }
139         }
140     }while(StackEmpty(&S) != OK);
141     DestoryStack(&S);
142     return ERes;
143 }
144 int main()
145 {
146     PosType start;
147     PosType end;
148     int i, j;
149     
150     scanf("%d %d", &g_m, &g_n);
151     start.x = 0;
152     start.y = 0;
153     end.x = g_m-1;
154     end.y = g_n-1;
155     
156     g_MazeMap = (int**)malloc(g_m*sizeof(int*));
157     g_MazeFootPrint = (PrintType**)malloc(g_m*sizeof(PrintType*));
158     for(i=0; i<g_m; ++i)
159     {
160         g_MazeMap[i] = (int*)malloc(g_n*sizeof(int));
161         g_MazeFootPrint[i] = (PrintType*)malloc(g_n*sizeof(PrintType));
162     }
163     
164     for(i=0; i<g_m; ++i)
165     {
166         for(j=0; j<g_n; ++j)
167         {
168             scanf("%d", &g_MazeMap[i][j]);
169         }
170     }
171     if(MazeShortPath(&start, &end) == OK)
172     {
173         MazePrintRes(&start, &end);
174     }
175     else
176     {
177         printf("no way!\n");
178     }
179     return 0;
180 }

 

posted on 2012-08-23 14:23  favourmeng  阅读(6335)  评论(0编辑  收藏  举报

导航