在上篇中,我们已经实现了用回溯法也就是递归的函数来实现迷宫问题,在我们学习的过程中,我们知道,非递归的实现就是采用的循环的方法。在前面相关的函数我已经写过了,在这里我就不进行例举了。
非递归实现的数据结构
typedef struct Maze{
int map[ROW][COL];
}Maze;
typedef struct Point{
int row;
int col;
}Point;
typedef Point SeqStackType;
typedef struct SeqStack{
SeqStackType* data;
size_t size;
size_t capacity;
}SeqStack;
其他相关函数的实现
/////////////////////////////////////////////////////////
/////////////////////非递归版本的实现///////////////////
////////////////////////////////////////////////////////
void SeqStackInit(SeqStack* stack){
if (stack == NULL){
return;
}
stack->size = 0;
stack->capacity = 1000;
stack->data = (SeqStackType*)malloc(stack->capacity*sizeof(SeqStackType));
}
void SeqStackResize(SeqStack* stack)//扩容
{
if (stack == NULL){
return;
}
if ((stack->size)<(stack->capacity)){
return;
}
stack->capacity = stack->capacity * 2 + 1;
SeqStackType* new = (SeqStackType*)malloc(stack->capacity*sizeof(SeqStackType));
int i = 0;
for (i = 0; i<stack->size; i++){
new[i] = stack->data[i];
}
free(stack->data);
stack->data = new;
}
void SeqStackPop(SeqStack* stack)//出栈
{
if (stack == NULL){
return;
}
if (stack->size == 0){
return;
}//空栈
--stack->size;
}
int SeqStackTop(SeqStack* stack, SeqStackType *value)//取栈顶元素
{
if (stack == NULL){
return;
}
if (stack->size == 0){
return;//空栈
}
*value = stack->data[stack->size - 1];
return value;
}
void SeqStackPush(SeqStack* stack, SeqStackType value)//入栈
{
if (stack == NULL){
return;
}
if ((stack->size) >= (stack->capacity)){
SeqStackResize(stack);
}
stack->data[stack->size++] = value;
}
void GetPathByLoop(Maze* maze, Point entry){
//1、创建一个栈,并且初始化,这个栈保存着走过的路径
SeqStack stack;
SeqStackInit(&stack);
//2、判定我们的入口能不能落脚,如果不能,说明参数非法
if (!CanStay(maze, entry)){
return;
}
//3、标记入口点,并将入口点入栈
Mark(maze, entry);
SeqStackPush(&stack, entry);
while (1){
//4、进入循环,获取当前的栈顶元素(栈顶元素一定能落脚)
Point cur;
int ret = SeqStackTop(&stack, &cur);
if (ret == 0){
//栈为空,说明回溯结束了
return;
}
//5、判定这个点是不是出口,如果是出口,直接函数返回
if (IsExit(maze, cur, entry)){
printf("找到了一条路径\n");
return;
}
//6、按照顺时针方向取相邻点,判定相邻点是否能落脚,
//如果能落脚,就标记并且入栈,立刻进行下一轮循环
Point up = cur;
up.row = -1;
if (CanStay(maze, up)){
Mark(&stack, up);
SeqStackPush(&stack, up);
continue;
}
Point right = cur;
right.col += 1;
if (CanStay(maze, right)){
Mark(maze, right);
SeqStackPush(&stack, right);
continue;
}
Point down = cur;
down.row += 1;
if (CanStay(maze, down)){
Mark(maze, down);
SeqStackPush(&stack, down);
continue;
}
Point left=cur;
left.col -= 1;
if (CanStay(maze, left)){
Mark(maze, left);
SeqStackPush(&stack, left);
continue;
}
//7、如果四个相邻的点都不能落脚,就出栈当前点,相当于回溯
SeqStackPop(&stack);
}
}
其他的函数,我在递归函数实现的过程中都进行了写入,在这里就不进行赘述了。