用递归来实现回溯应该是很常见的一种思路。因为回溯法最核心的问题就是如何保存每一步已经选择过的方案信息,以供回退时继续选择下一个方案。而使用递归函数恰好利用了函数调用栈保存了每一步的“进度”,使得每一次函数返回时上一级函数可以继续这个“进度”。
虽然递归实现起来简单易理解,但使用递归并不是唯一的选择,而且,使用递归总给人一种效率可能不高的感觉。通过简单改造,我们也可以使用非递归的方法来实现回溯法。具体思路是:
为了保存每一步的“进度”,可以这样做,用一个int choose[25]数组来充当一个栈,数组每个元素可以从0取到3,分别代表上下左右。当进行到某一步时,按上下左右的顺序进行试探,对应的数组元素就从0开始变大,假设可以向下走一步,此时数组元素的值就变为了1,这样就保存了这一步的“进度”信息,当发生回退时,可以继续从2开始,即从左边继续试探。还要用一个int top来充当栈顶指针,当前进一步top就加1,回退一步top就减1。具体实现代码如下:
#include<stdio.h>
//定义上下左右方向
int direction[4][2] = {-1,0,1,0,0,-1,0,1};
int puzzle[5][5] = {
1,1,1,1,1,
0,0,1,0,1,
1,0,0,0,1,
1,0,0,0,0,
1,1,1,1,1
};
int path[25][2] = {0}; //用于记录路径
int choose[25] = {0}; //记录每一步已经选择到了哪个方向,0-3分别表示表示上下左右,全部初始为0
int top = 0; //栈顶指针,总是指向最后一个元素
void getpath(i