花了一下午时间,完成了纯C语言版的迷宫求解,源码见下:
Main_3_2_maze.c:
#include "Stack_maze.h" #define ROW 10 #define LINE 10 Cell c[LINE][ROW]; void InitCell() { int i = 0 ; int j = 0; for(i = 0 ; i < LINE ; i++) { for(j = 0 ; j < ROW ; j++) { c[i][j].pix.x = i; c[i][j].pix.y = j; c[i][j].IsFilling = 1; c[i][j].IsRun = 0; } } } void PrintCell() { int i = 0; int j = 0; char filled = '#'; char unfilled = '-'; for(i = 0 ; i < LINE ; i++) { printf("\n\n"); for(j = 0 ; j < ROW ; j++) { switch(c[i][j].IsFilling) { case 0: printf("%c%d%d\t",unfilled,c[i][j].pix.x,c[i][j].pix.y);break; case 1: printf("%c%d%d\t",filled,c[i][j].pix.x,c[i][j].pix.y);break; //case 0: printf("%c\t",unfilled);break; //case 1: printf("%c\t",filled);break; } } } printf("\n"); } int IsPixelLegal(X x, Y y) { if((x < 0 )|| (x > LINE)) { return -1; } if((y < 0 )|| (y > ROW)) { return -1; } return 1; } void SetCellFilled(X x, Y y) { if(IsPixelLegal(x,y)) { c[x][y].IsFilling = 1; } else { printf("illegal cell !\n"); } } void SetCellUnFilled(X x, Y y) { if(IsPixelLegal(x,y)) { c[x][y].IsFilling = 0; } else { printf("illegal cell !\n"); } } void SetCellRun(X x, Y y) { if(IsPixelLegal(x,y)) { c[x][y].IsRun = 1; } else { printf("illegal cell !\n"); } } int IsCellRun(X x,Y y) { if(IsPixelLegal(x,y)) { return c[x][y].IsRun; } else { printf("illegal cell !\n"); } return -1; } int IsCellFilled(X x,Y y) { if(IsPixelLegal(x,y)) { return c[x][y].IsFilling; } else { printf("illegal cell !\n"); } return -1; } void GetNextCell(Cell curr,Cell *next) { memset(next,0,sizeof(Cell)*4); if(IsPixelLegal(curr.pix.x,curr.pix.y)) { //top if(curr.pix.x - 1 >= 0) { next[0].pix.x = curr.pix.x - 1; next[0].pix.y = curr.pix.y; memcpy(&next[0],&c[curr.pix.x - 1][curr.pix.y],sizeof(Cell)); } else { next[0].pix.x = -1; next[0].pix.y = -1; } //bottom if(curr.pix.x + 1 < LINE) { next[1].pix.x = curr.pix.x + 1; next[1].pix.y = curr.pix.y; memcpy(&next[1],&c[curr.pix.x + 1][curr.pix.y],sizeof(Cell)); } else { next[1].pix.x = -1; next[1].pix.y = -1; } //left if(curr.pix.y - 1 >= 0) { next[2].pix.x = curr.pix.x; next[2].pix.y = curr.pix.y - 1; memcpy(&next[2],&c[curr.pix.x][curr.pix.y - 1],sizeof(Cell)); } else { next[2].pix.x = -1; next[2].pix.y = -1; } //right if(curr.pix.y + 1 < ROW) { next[3].pix.x = curr.pix.x; next[3].pix.y = curr.pix.y + 1; memcpy(&next[3],&c[curr.pix.x ][curr.pix.y + 1],sizeof(Cell)); } else { next[3].pix.x = -1; next[3].pix.y = -1; } } else { printf("error !!\n"); } } int Is2CellEqual(Cell a, Cell b) { if((a.pix.x == b.pix.x) && (a.pix.y == b.pix.y)) { return 1; } return -1; } void GetNextStep(Cell *c,Cell *next) { int i = 0; for(i = 0 ; i < 4 ; i++) { if((c[i].IsRun == 0) && (IsPixelLegal(c[i].pix.x,c[i].pix.y) == 1) && (IsCellFilled(c[i].pix.x,c[i].pix.y) == 0)) { //printf("get next step %x%x\n",c[i].pix.x,c[i].pix.y); memcpy(next,&c[i],sizeof(Cell)); break; } } } void PrintPix(X x, Y y) { printf("----- (%x,%d)\n",x,y); } void SetErrorCell(Cell* c) { c->pix.x = -1; c->pix.y = -1; } int RunMaze(Cell current,Cell goal) { if(IsPixelLegal(current.pix.x,current.pix.y) && IsPixelLegal(goal.pix.x,goal.pix.y)) { PStack p; p = (PStack)malloc(sizeof(Stack)); if(!p) { return -1; } InitStack(p); Cell next[4]; Cell step; Cell cur; memcpy(&cur,¤t,sizeof(Cell)); SetCellRun(current.pix.x,current.pix.y); int i = 0; Push(p,current); while(1) { SetErrorCell(&step); GetNextCell(current,next); GetNextStep(next,&step); //printf("cur %d%d step %d%d\n",current.pix.x,current.pix.y,step.pix.x,step.pix.y); if(Is2CellEqual(step,goal) == 1) { printf("find it !!!\n"); PrintStack(p); break; } if(step.pix.x != -1) { SetCellRun(step.pix.x,step.pix.y); Push(p,step); //printf("Push !! %d\n",step.pix.x); memcpy(¤t,&step,sizeof(Cell)); } else { //stack has content if(IsStackEmpty(p) == 0) { Pop(p, &step); GetTop(p,¤t); //printf("Pop\n"); } else { printf("no conten\n"); } } if(i++ >= 50) { break; } if(Is2CellEqual(cur,step) == 1) { printf("can't find it !!!\n"); break; } } DestoryStack(p); } else { printf("wrong cell !!\n"); } return -1; } void Test_GetNextCell() { Cell cur,next[4]; cur.pix.x = 0; cur.pix.y = 0; GetNextCell(cur,next); int i = 0; for(i = 0 ; i < 4 ; i++) { printf("next %d%d\n",next[i].pix.x,next[i].pix.y); } } int main(int argc, char** argv) { InitCell(); int i = 0; for(i = 1 ; i < 8; i ++) { SetCellUnFilled(i,1); } for(i = 2; i < 9; i++) { SetCellUnFilled(8,i); } for(i = 1 ; i < 9; i++) { SetCellUnFilled(i,8); } for(i = 1; i < 4; i++) { SetCellUnFilled(i,2); } SetCellUnFilled(5,2); SetCellUnFilled(5,3); SetCellUnFilled(5,4); SetCellUnFilled(4,6); SetCellUnFilled(6,4); SetCellUnFilled(6,5); SetCellUnFilled(7,5); PrintCell(); Cell cur,goal; cur.pix.x = 1; cur.pix.y = 1; goal.pix.x = 8; goal.pix.y = 8; RunMaze(cur,goal); }
库:
Stack_maze.c:
#include "Stack_maze.h" /*3.1 3.2*/ int InitStack(PStack S) { S->base = (SElemType *)malloc(sizeof(SElemType) * STACK_INIT_SIZE); if(!S->base) { exit(0); } S->top = S->base; S->stackSize = STACK_INIT_SIZE; return 1; } int GetTop(PStack S,SElemType *e) { if(S->base == S->top) { return -1; } *e = *(S->top -1); return 1; } int Push(PStack S,SElemType e) { if(S->top - S->base >= S->stackSize) { S->base = (SElemType *)realloc(S->base,(S->stackSize + STACK_INCRE_SIZE) * sizeof(SElemType)); if(!S->base) { return -1; } S->top = S->base + S->stackSize; S->stackSize += STACK_INCRE_SIZE; } //*S->top++ = e; memcpy(S->top,&e,sizeof(SElemType)); S->top ++; return 1; } int Pop(PStack S,SElemType *e) { if(S->base == S->top) { return -1; } *e = * -- S->top; } int ClearStack(PStack S) { S->top = S->base; return 1; } int DestoryStack(PStack S) { free(S->base); } void PrintStack(PStack S) { PStack p; p = S; int i = 0; while(p->top != p->base) { i++; p->top --; printf("(%d,%d)\t",p->top->pix.x,p->top->pix.y); } p->top += i; printf("\n"); } int IsStackEmpty(PStack S) { return ((S->base == S->top) ? 1 : 0); }
Stack_maze.h:
#ifndef _STACK_H #define _STACK_H #include <stdlib.h> #include <string.h> #include <stdio.h> typedef int X; typedef int Y; typedef struct PINT { X x; Y y; }Pixel; typedef struct _CELL { Pixel pix; int IsFilling; //0:no filled , 1: filled int IsRun;// 0: have run , 1: first run }Cell; #define STACK_INIT_SIZE 100 #define STACK_INCRE_SIZE 50 typedef Cell SElemType ; typedef struct SqStack { SElemType *base; SElemType *top; int stackSize; }Stack,*PStack; int InitStack(PStack S); int GetTop(PStack S,SElemType *e); int Push(PStack S,SElemType e); int Pop(PStack S,SElemType *e); int ClearStack(PStack S); int DestoryStack(PStack S); void PrintStack(PStack S); #endif
编译方法如前所述,运行效果如下:#表示该处被填充,无法通过;-表示该处可以通过。
tiger@ubuntu:/mnt/hgfs/E/Lessons/MyExercise/DS/3$ gcc -o main_3_2_maze main_3_2_maze.c ./libStack_maze.so tiger@ubuntu:/mnt/hgfs/E/Lessons/MyExercise/DS/3$ ./main_3_2_maze #00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 -11 -12 #13 #14 #15 #16 #17 -18 #19 #20 -21 -22 #23 #24 #25 #26 #27 -28 #29 #30 -31 -32 #33 #34 #35 #36 #37 -38 #39 #40 -41 #42 #43 #44 #45 -46 #47 -48 #49 #50 -51 -52 -53 -54 #55 #56 #57 -58 #59 #60 -61 #62 #63 -64 -65 #66 #67 -68 #69 #70 -71 #72 #73 #74 -75 #76 #77 -78 #79 #80 #81 -82 -83 -84 -85 -86 -87 -88 #89 #90 #91 #92 #93 #94 #95 #96 #97 #98 #99 find it !!! (8,7) (8,6) (8,5) (7,5) (6,5) (6,4) (5,4) (5,3) (5,2) (5,1) (4,1) (3,1) (2,1) (1,1) tiger@ubuntu:/mnt/hgfs/E/Lessons/MyExercise/DS/3$
好了,栈这一块暂时告一段落!