1.解决存储问题
实现迷宫的存储。用一个二维矩阵存储
如下列迷宫:
0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,
1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,
0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,
1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,
1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,
0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,
0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,
0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,
1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,
0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,
0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,
2.解决移动问题
考虑移动:
有8个方向:
方位 方向代码(dir) 行移动 (move[dir].vert) 列移动(move[dir].horiz)
N 0 -1 0
NE 1 -1 1
E 2 0 1
SE 3 1 1
S 4 1 0
SW 5 1 -1
W 6 0 -1
NW 7 -1 -1
数据结构表示:
typedef struct{
short int vert;
short int horiz;
} offsets;
offsets move[8];
若当前位置是maze[row][col]
那么下一个位置是maze[next_row][next_col];
next_row=row+move[dir].vert;
next_col=col+move[dir].horiz;
3.解决边界问题
并不是每个移动都有8个位置如边和角的位置,所以为啦避免边界检查,所以再加上一圈边界
若是m*n个元素 则需要(m+2)*(n+2)个存储空间
如下图:
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1,
1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1,
1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,
1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,
1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1,
1,0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,1,
1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,
1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,
1,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,
1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1,
1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
4.这里所用的栈即是上一篇写的基础栈。
代码如下:
1 #include<stdio.h> 2 #define MAX_STACK_SIZE 100 //栈的最大元素数 3 4 5 int EXIT_ROW=11,EXIT_COL=15,TRUE=1,FALSE=0,top; 6 //出口的行列,top栈顶 7 short int maze[13][17]={ //[m+2][p+2] ; //15*11迷宫 1,1开始,15,11结束 8 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9 1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1, 10 1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1, 11 1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1, 12 1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1, 13 1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1, 14 1,0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,1, 15 1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1, 16 1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1, 17 1,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1, 18 1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1, 19 1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1, 20 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 21 }; 22 short int mark[13][17]={ //[m+2][p+2] ; //走过的路程记录 23 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 24 1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1, 25 1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1, 26 1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1, 27 1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1, 28 1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1, 29 1,0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,1, 30 1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1, 31 1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1, 32 1,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1, 33 1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1, 34 1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1, 35 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 36 }; 37 38 typedef struct{ 39 short int vert; 40 short int horiz; 41 } offsets; 42 offsets move[8]={// dir vert horiz 可以移动的位置8个方向 43 -1,0, // 0 上 44 -1,1, // 1 右上 45 0,1, // 2 右 46 1,1, // 3 右下 47 1,0, // 4 下 48 1,-1, // 5 左下 49 0,-1, // 6 左 50 -1,-1 // 7 左上 51 }; 52 53 typedef struct{ //定义栈的基础元素 54 short int row; 55 short int col; 56 short int dir; 57 }element; 58 element stack[MAX_STACK_SIZE]; 59 60 bool IsFull(int *top ); 61 void Add(int *top,element item); 62 bool IsEmpty(int *top ); 63 element Delete(int *top); 64 65 66 void path(void) 67 { 68 int i,row,col,next_row,next_col,dir,found=FALSE; 69 element position; 70 71 mark[1][1]=1; //初始位置 记录已经走过 72 top=0; //栈顶为0 73 stack[0].row=1; //给栈顶赋值 74 stack[0].col=1; 75 stack[0].dir=1; 76 77 while( top > -1 && !found) { 78 //当栈里元素不空且没有找到路径时做循环 79 position = Delete(&top); //找不到出口时回到上一个位置 80 row = position.row; 81 col = position.col; 82 dir = position.dir; 83 84 while( dir < 8 && !found ){ //每一个方向 85 //主要用于找到出口 86 next_row=row+move[dir].vert; //每一个方向的下一步 87 next_col=col+move[dir].horiz; 88 if(next_row ==EXIT_ROW &&next_col ==EXIT_COL) //若发现到出口结束 89 { 90 found=TRUE; 91 } 92 else if(!maze[next_row][next_col] && !mark[next_row][next_col]){ 93 //若原矩阵和记录矩阵都是 0(即未走过且不是墙壁) 94 mark[next_row][next_col]=1; //记录这个地方已经走过 (封锁避免重复走) 95 96 position.row=row; //当前位置换方向 97 position.col=col; 98 position.dir=++dir; 99 Add(&top,position); //入栈 添加回溯点 100 row=next_row; //下一个位置 重新从上部开始比较 101 col=next_col; 102 dir=0; 103 } 104 else ++dir; 105 } 106 } 107 108 if(found){ 109 printf("the path is:\n"); 110 printf("row col\n"); 111 112 for(i=0;i<=top;i++){ 113 printf("%2d%5d\n",stack[i].row,stack[i].col); 114 } 115 printf("%2d%5d\n",row,col); //下一个元素 116 printf("%2d%5d\n",EXIT_ROW,EXIT_COL); //出口 117 } 118 else 119 printf("the maze does not have a path\n"); 120 121 } 122 int main() 123 { 124 path(); 125 int i,j; 126 /* for(i=0;i<13;i++) 用于查看记录矩阵 127 { 128 for(j=0;j<17;j++) 129 printf("%d",mark[i][j]); 130 printf("\n"); 131 }*/ 132 133 return 0; 134 } 135 136 137 bool IsFull(int * top )//1为满0为不满 138 { 139 if(*top >=MAX_STACK_SIZE-1){ 140 return 1; 141 } 142 else{ 143 return 0; 144 } 145 } 146 147 bool IsEmpty(int *top)//1为空 0为不空 148 { 149 if(*top == -1){ 150 return 1; 151 } 152 else{ 153 return 0; 154 } 155 } 156 void Add(int *top,element item) 157 { 158 if(*top >=MAX_STACK_SIZE-1){ 159 printf("栈满"); 160 return ; 161 } 162 else 163 stack[++(*top)]=item; 164 } 165 element Delete(int *top) 166 { 167 if(*top == -1){ 168 printf("栈空"); 169 } 170 return stack[(*top)--]; 171 }
结果:
the path is: row col 1 1 2 2 1 3 1 4 1 5 2 4 3 5 3 4 4 3 5 3 6 2 7 1 8 2 9 3 9 4 8 5 7 6 7 7 8 8 9 8 10 9 10 10 9 11 9 12 9 13 8 14 9 15 10 15 11 15 走过路径为9数字的; 11111111111111111 19199911999111111 11909119111991111 10119999111199111 11191111101191101 11191001011111111 19911011101001011 19111199111111111 10911911911111911 11199011911999091 10011111099111191 10100111110111101 11111111111111111 真实路径; 11111111111111111 19199911111111111 11909111111111111 10119911111111111 11191111101111101 11191001011111111 11911011101001011 19111199111111111 10911911911111911 11199011911999091 10011111099111111 10100111110111101 11111111111111111 由于最后2步没有入栈所以需要自己输出一下