迷宫问题--小结

Level 0:递归查找一条可用路径

已知int maze[5][5]矩阵表示的迷宫,求解一条(0,0)至(4,4)的路径;

思路:

1)双向链表存储,走过路径;

2)递归调用char shortest_path(Position*currrentPos, Position* desPos);实现查找

递归调用char shortest_path()的返回情况:

1.在该节点,尝试过 右、下、左、上 四个方向,都无法走通,该节点是条死路, 则return 'n'; 回退到上一节点,在上一节点寻找其他可走的路;

2.已经到达目的地desPos,return 'y';  递归返回 'y',直到第一次调用char shortest_path()之后,结束递归调用;

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 typedef struct {
5 int _X; //
6   int _Y; //
7  }Position; //节点坐标信息,保存路径
8
9 typedef struct _Node{
10 Position _pos;
11 struct _Node *next;
12 struct _Node *pre;
13 }Node;
14
15 typedef struct{
16 Node* head;
17 Node* tail;
18 }Path; //路径的head、tail,访问路径
19
20 int maze[5][5]={
21 0,1,0,0,0,
22 0,1,1,1,0,
23 0,0,0,0,0,
24 0,1,0,1,1,
25 0,1,0,0,0,
26 };
27
28 int offset[4][2]={
29 0,1,
30 1,0,
31 0,-1,
32 -1,0,
33 };//右、下、左、上
34
35 Path path; //路径
36
37 void step_forward(int pos_x,int pos_y) //前进
38 {
39 Node* node = (Node*)malloc(sizeof(Node));
40 if(node!=NULL)
41 {
42 node->_pos._X=pos_x;
43 node->_pos._Y=pos_y;
44 node->pre=NULL;
45 node->next=NULL;
46 if(path.tail!=NULL)
47 {
48 path.tail->next=node;
49 node->pre=path.tail;
50 path.tail=node;
51 maze[node->_pos._X][node->_pos._Y]=-1;
52 }
53 }
54 }
55
56 void step_backforward()
57 {
58 if(path.tail!=NULL)
59 {
60 Node* newtail=path.tail->pre;
61 path.tail->pre->next=NULL;
62 free(path.tail);
63 path.tail=newtail;
64 }
65 }
66 char is_can_go(int pos_x, int pos_y)
67 {
68 if(pos_x < 0 || pos_x > 4
69 || pos_y < 0 ||pos_y > 4
70 || (maze[pos_x][pos_y]!=0))
71 return 'n'; //跃出地图边界,或者是墙,或者是死路,返回'n'
72 // if(path.tail->pre!=NULL&&(path.tail->pre->_pos._X == pos_x && path.tail->pre->_pos._Y==pos_y))
73 // return 'n'; //方向是返回的方向,返回'n'
74 return 'y'; //其他返回'y'
75 }
76
77 char shortest_path(Position* currentPos,Position* desPos)
78 {
79 int i;
80 if(currentPos->_X == desPos->_X && currentPos->_Y == desPos->_Y) //如果已经到达目的地,回退
81 return 'y';
82 for(i=0;i<4;++i)
83 {
84 int newPos_X=currentPos->_X+offset[i][0];
85 int newPos_Y=currentPos->_Y+offset[i][1];
86 if(is_can_go(newPos_X,newPos_Y)=='y') //如果当前位置,可以移动,则移动方格
87 {
88 step_forward(newPos_X,newPos_Y);
89 currentPos->_X=newPos_X;
90 currentPos->_Y=newPos_Y;
91 if('y'==shortest_path(currentPos,desPos)) //已经到达终点,则返回'y'
92 return 'y';
93 else //否则,回退
94 {
95 step_backforward();
96 currentPos->_X=path.tail->_pos._X;
97 currentPos->_Y=path.tail->_pos._Y;
98 }
99 }
100 }
101 return 'n';
102 }
103
104 void initialize()
105 {
106 path.head=(Node*)malloc(sizeof(Node));
107 path.head->next=NULL;
108 path.head->pre=NULL;
109 path.head->_pos._X=0;
110 path.head->_pos._Y=0;
111 path.tail=path.head;
112 maze[0][0]=-1;
113 }
114
115 void print_path()
116 {
117 Node *node_ptr;
118 node_ptr=path.head;
119 while(node_ptr!=NULL)
120 {
121 printf("(%d, %d)\n",node_ptr->_pos._X,node_ptr->_pos._Y);
122 node_ptr=node_ptr->next;
123 }
124 }
125
126 int main()
127 {
128 Position* currentPos;
129 Position*desPos;
130 initialize();
131
132 currentPos=(Position*)malloc(sizeof(Position));
133 currentPos->_X=0;
134 currentPos->_Y=0;
135
136 desPos=(Position*)malloc(sizeof(Position));
137 desPos->_X=4;
138 desPos->_Y=4;
139
140 shortest_path(currentPos,desPos);
141 print_path();
142 system("pause");
143 return 0;
144 }

不足之处:代码有点凌乱。

注意点:

1.递归调用,在何时返回,怎么返回。

2.在返回'n'时,由于char* currentPos是指针变量,实际数据存储在堆区域,已经被修改,需要重新将tail所指向的堆区域的值复制给currentPos。

3.step_forward函数,前进一步时,需要maze[][]中对应项赋值为-1,避免回退;

posted on 2011-02-22 17:25  loveclover  阅读(274)  评论(0编辑  收藏  举报

导航