码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构应用实例#栈#迷宫寻路

时间:2015-09-15 21:56:22      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

使用数据结构 栈(Stack)来实现一种低级的迷宫寻路的功能。
低级是因为无法判断路径是不是最短的。

这里使用的栈结构如图 (这图我选择死亡...)

技术分享
注意结构体里DataType的实际含义,是另外一个结构体,用于储存二维位置x,y


地图使用一个10x10的二维数组来表示,数字1表示该点是墙壁,0表示可以行走,2表示已经走过的地方。

我们用栈来储存走过的位置,比如我们从起点(4,0)出发,就把(4,0)压入栈,并把该点数值改为2,意为已经来过了。
如果遇到死路,那就不停地出栈,直到栈顶的这个点周围有路可走为止。

 

逻辑部分伪代码如下

while(没有到达终点)
{
  if(上下左右四个方向有路可走)
  {
    将可以走的那个位置(不是当前位置!)压入栈
  }
  else
  {
    出栈
  }
}

 

首先是栈的头文件,注意栈结构体内容的具体定义

Stack.h

 1 #ifndef _STACK_H_
 2 #define _STACK_H_
 3 
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 
 7 //以下两个数据大小视实际情况而定
 8 //初始栈容量
 9 #define STACK_INIT_SIZE 20
10 //每次扩容的增量
11 #define STACKINCREMENT 10
12 
13 //迷宫地图
14 int Maze[10][10];
15 
16 //表示位置
17 struct xy
18 {
19     int x, y;
20 };
21 typedef struct xy XY;
22 typedef  XY DataType;
23 
24 struct stack
25 {
26     //指向栈最顶上的元素的接下来一个位置
27     //表示新入栈的值可以放在指向的地方
28     DataType *Top;
29     //指向栈底部,最里面的元素
30     DataType *Bottom;
31     //表示了当前栈的容量
32     int stacksize;
33 };
34 typedef struct stack STACK;
35 
36 //新建栈
37 int InitStack(STACK *S);
38 
39 //销毁栈
40 int DestroyStack(STACK *S);
41 
42 //返回顶层元素
43 int GetTop(STACK S,int *x,int *y);
44 
45 //Push操作,入栈,压栈
46 int Push(STACK *S, int x,int y);
47 
48 //Pop操作,出栈
49 int Pop(STACK *S);
50 
51 #endif

然后是定义

Stack.c

 1 #include"Stack.h"
 2 
 3 int InitStack(STACK *S)
 4 {
 5     //创建出设定长度的顺序表,地址赋给bottom指针
 6     S->Bottom = (DataType*)malloc(STACK_INIT_SIZE*sizeof(DataType));
 7     if (!S->Bottom)
 8     {
 9         return 0;
10     }
11     S->stacksize = STACK_INIT_SIZE;
12     S->Top = S->Bottom;
13     return 1;
14 }
15 
16 int DestroyStack(STACK *S)
17 {
18     S->Top = NULL;
19     free(S->Bottom);
20     S->Bottom = NULL;
21     return 1;
22 }
23 
24 int GetTop(STACK S, int *x, int *y)
25 {
26     if (S.Bottom != S.Top)
27     {
28         //由于top指向的是最顶上元素的下一个位置
29         //所以取出最顶上元素的时候
30         //要把top减去1
31         *x = ((S.Top - 1)->x);
32         *y = ((S.Top - 1)->y);
33         return 1;
34     }
35     return 0;
36 }
37 
38 int Push(STACK *S, int x,int y)
39 {
40     //当超出当前栈的容量时
41     //这里应该只有等于的情况
42     //而不会大于
43     if ((S->Top - S->Bottom) >= S->stacksize)
44     {
45         //realloc函数将开辟指定的储存空间
46         //并将原来的数据全部移到这个新的储存空间
47         S->Bottom = (DataType*)realloc(S->Bottom, (S->stacksize + STACKINCREMENT)*sizeof(DataType));
48         if (!S->Bottom)
49         {
50             return 0;
51         }
52         //由于重新开辟了空间
53         //需要重新根据bottom指针的位置指定top
54         S->Top = S->Bottom + S->stacksize;
55         //最后增加当前栈容量
56         S->stacksize += STACKINCREMENT;
57     }
58     //再把入栈的数据存放好
59     (S->Top)->x = x;
60     (S->Top)->y = y;
61     S->Top++;
62 
63     //在地图上将该点标为2
64     Maze[x][y] = 2;
65     return 1;
66 }
67 
68 //将该点丢弃
69 int Pop(STACK *S)
70 {
71     if (S->Bottom == S->Top)
72     {
73         printf("Empty Stack!Can not pop!\n");
74         return 0;
75     }
76     //top指针先减1再取值
77     --S->Top;
78     return 1;
79 }

 

寻路的逻辑放在了main函数里,迷宫地图的定义也在这里

main.c

二维数组Maze存放了迷宫的信息,你也可以自己改改*。

  1 #include"Stack.h"
  2 
  3 #define Up 1
  4 #define Right 2
  5 #define Down 3
  6 #define Left 4
  7 //代表已无路可走
  8 //End of Road
  9 #define EOR 5
 10 
 11 //迷宫的地图
 12 //墙壁表示为1,可走的地方表示为0,走过的地方表示为2
 13 //入口为(4,0),出口为(0,8)
 14 //可自行更改,但请确保有通路
 15 
 16 Maze[10][10] = { 
 17 //0,1,2,3,4,5,6,7,8,9
 18 1,1,1,1,1,1,1,1,0,1,     //0
 19 1,0,0,0,0,0,0,1,0,1,     //1
 20 1,0,1,0,1,1,1,1,0,1,     //2
 21 1,0,1,0,1,0,0,0,0,1,     //3
 22 0,0,1,0,1,0,1,0,1,1,     //4
 23 1,0,1,0,1,0,1,0,1,1,     //5
 24 1,1,0,0,1,0,1,0,1,1,     //6
 25 1,0,0,1,1,0,1,0,1,1,     //7
 26 1,0,0,0,0,0,1,0,0,1,     //8
 27 1,1,1,1,1,1,1,1,1,1 };  //9
 28 
 29 //打印结果
 30 int Print()
 31 {
 32     int lop, lop2;
 33     for (lop = 0; lop < 10; lop++)
 34     {
 35         for (lop2 = 0; lop2 < 10; lop2++)
 36         {
 37             if (Maze[lop][lop2] == 2)
 38             {
 39                 printf("1");
 40             }
 41             else
 42             {
 43                 printf(" ");
 44             }
 45         }
 46         printf("\n");
 47     }
 48     return 1;
 49 }
 50 
 51 int GameOver(STACK s, XY *loc,XY End)
 52 {
 53     GetTop(s, &(loc->x), &(loc->y));
 54     if (loc->x == End.x && loc->y == End.y)
 55     {
 56         return 1;
 57     }
 58     else
 59     {
 60         return 0;
 61     }
 62 }
 63 
 64 //1 up.2 right.3 down.4 left
 65 //看看当前位置的上下左右还有没有能走的地方
 66 int SearchPath(STACK s, XY loc)
 67 {
 68     int x, y;
 69     x = loc.x;
 70     y = loc.y;
 71 
 72     //Up Available?
 73     if (x != 0)
 74     {
 75         if (!Maze[x - 1][y])
 76         {
 77             return Up;
 78         }
 79     }
 80     //Right ?
 81     if (y != 9)
 82     {
 83         if (!Maze[x][y + 1])
 84         {
 85             return Right;
 86         }
 87     }
 88     //Down?
 89     if (x != 9)
 90     {
 91         if (!Maze[x + 1][y])
 92         {
 93             return Down;
 94         }
 95     }
 96     //Left?
 97     if (y != 0)
 98     {
 99         if (!Maze[x][y - 1])
100         {
101             return Left;
102         }
103     }
104     return EOR;
105 }
106 
107 int main()
108 {
109     //储存走出迷宫的路径
110     STACK Path;
111     //储存当前位置
112     XY loc;
113     //起点终点的位置
114     XY Start = { 4,0 }, End = { 0,8 };
115 
116     InitStack(&Path);
117     //将起点入栈
118     Push(&Path, Start.x, Start.y);
119 
120     //开始
121     while (!GameOver(Path, &loc, End))
122     {
123         switch (SearchPath(Path, loc))
124         {
125         case Up:
126             Push(&Path, loc.x - 1, loc.y);
127             break;
128         case Right:
129             Push(&Path, loc.x, loc.y + 1);
130             break;
131         case Down:
132             Push(&Path, loc.x + 1, loc.y);
133             break;
134         case Left:
135             Push(&Path, loc.x, loc.y - 1);
136             break;
137         case EOR:
138             Pop(&Path);
139             break;
140         default:
141             printf("Shit Happened! Check your code!\n");
142             break;
143         }
144     }
145     Print();
146     DestroyStack(&Path);
147     return 0;
148 }

 

最后运行结果如图

技术分享

有一行多出来的1,因为打印的是走过的路径。

 

*如果你想自己更改迷宫地图的话,请务必记得更改相应的起点和终点(114行)

数据结构应用实例#栈#迷宫寻路

标签:

原文地址:http://www.cnblogs.com/makejeffer/p/4811500.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!