使用数据结构 栈(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行)
时间: 2024-09-27 01:17:24