请问这个是递归和非递归一起实现一条通路
还是各自实现各自的通路
在C语言中,实现迷宫的解决方案有很多种,其中一种常见的方法是使用递归和非递归结合的方式来实现。具体来说,我们可以定义一个函数,使用递归的方法来搜索通向出口的路径,同时在函数内部使用非递归的方法来处理边界条件和回溯操作。
为了保证和柔性数组一样的性质,都是在堆上开辟的!我们所有的都需要用malloc开辟空间;柔型数组是一个malloc整体一块开辟的;用指针代替柔性数组,就要分开开辟:一个开辟除指针以外的大小的而空间;一个开辟指针所需大小的空间!
(1)利用指针代替柔型数组;实际上就是从一步到两步的过程;柔性数组只需要一次malloc;而指针形式就需要两次malloc;两次malloc就需要两次free;
(2)第一次malloc是动态创建除指针以外所需的空间;第二次malloc是动态创建指针所需大小的空间;
(3)成功开辟后就使用,通过指针ps->arr来查看内存发现已经被赋值;
(4)用完了,我们就用realloc进行扩容,我们就只需要对指针部分进行扩容;我们用一个新的指针ptr进行接收,扩容成功后;把新指针ptr赋值给旧指针ps->arr;
(5)最后在进行ps->arr指针和ps指针的释放,free(ps->arr),ps->arr = NULL ;free(ps),ps = NULL
很抱歉,参考资料与问题不匹配,以下是针对 C 语言迷宫递归和非递归实现的问题的回答:
对于一条迷宫的通路,递归和非递归实现确实可以各自实现,也可以一起实现同一条通路。
一般来讲,递归实现可以更加轻松地理解迷宫走法和判断可行性,但在实现时需要注意递归深度的限制。非递归实现一般需要维护一个栈来记录走过的路径,更加灵活,但实现起来可能稍微复杂一些。
以下是基于字符数组表示迷宫的递归实现代码示例:
#include <stdio.h>
// 迷宫数组,1 表示墙,0 表示通路
char map[5][5] = {
{'1', '1', '1', '1', '1'},
{'1', '0', '0', '0', '1'},
{'1', '1', '0', '1', '1'},
{'1', '0', '0', '0', '1'},
{'1', '1', '1', '1', '1'}
};
// 当前位置是否可通,参数为坐标
int is_valid(int row, int col) {
if (row < 0 || row >= 5 || col < 0 || col >= 5) {
// 越界
return 0;
}
return map[row][col] == '0';
}
// 递归实现函数,参数为当前位置的坐标和目标位置的坐标
int find_path(int row, int col, int dest_row, int dest_col) {
if (row == dest_row && col == dest_col) {
// 已经到达目标位置
return 1;
}
if (!is_valid(row, col)) {
// 当前位置不可通
return 0;
}
// 标记当前位置已访问
map[row][col] = '2';
// 搜寻四个方向
if (find_path(row - 1, col, dest_row, dest_col) ||
find_path(row, col - 1, dest_row, dest_col) ||
find_path(row + 1, col, dest_row, dest_col) ||
find_path(row, col + 1, dest_row, dest_col)) {
return 1;
}
// 四个方向都无法到达目标位置,回溯
map[row][col] = '0';
return 0;
}
int main() {
int start_row = 1, start_col = 1;
int dest_row = 3, dest_col = 3;
if (find_path(start_row, start_col, dest_row, dest_col)) {
printf("path found!\n");
} else {
printf("no path found\n");
}
return 0;
}
以上代码使用递归实现了在迷宫中找出一条从起点到终点的路径。具体实现过程中,我们首先需要定义一个迷宫数组 map
,其中 1
表示墙,0
表示通路 (非障碍物)。is_valid
函数用于判断指定位置是否可通,find_path
函数使用递归进行搜索,如果找到一条可行的路径则返回 1,否则返回 0。在递归搜索过程中,我们通过修改 map
数组的内容来标记已访问过的位置,同时将四个方向作为下一次递归的参数进行遍历。最后,将已访问过的位置标记为 2
可以简化回溯操作。
以下是基于栈数据结构实现非递归搜索迷宫的代码示例:
#include <stdio.h>
// 迷宫数组,1 表示墙,0 表示通路
char map[5][5] = {
{'1', '1', '1', '1', '1'},
{'1', '0', '0', '0', '1'},
{'1', '1', '0', '1', '1'},
{'1', '0', '0', '0', '1'},
{'1', '1', '1', '1', '1'}
};
// 当前位置是否可通,参数为坐标
int is_valid(int row, int col) {
if (row < 0 || row >= 5 || col < 0 || col >= 5) {
// 越界
return 0;
}
return map[row][col] == '0';
}
// 坐标结构体
struct Point {
int row;
int col;
};
// 栈结构体
struct Stack {
struct Point arr[25];
int top;
};
// 初始化栈
void init_stack(struct Stack* stack) {
stack->top = -1;
}
// 检查栈是否为空
int is_empty(struct Stack* stack) {
return stack->top == -1;
}
// 入栈
void push(struct Stack* stack, struct Point point) {
stack->arr[++stack->top] = point;
}
// 出栈
struct Point pop(struct Stack* stack) {
return stack->arr[stack->top--];
}
// 非递归搜索函数,参数为起点和终点坐标
int search(struct Point start, struct Point dest) {
struct Stack stack;
init_stack(&stack);
push(&stack, start);
while (!is_empty(&stack)) {
struct Point cur = pop(&stack);
if (cur.row == dest.row && cur.col == dest.col) {
// 已经到达目标位置
return 1;
}
if (is_valid(cur.row, cur.col)) {
// 标记当前位置已访问
map[cur.row][cur.col] = '2';
// 将四个方向入栈
struct Point next;
next.row = cur.row - 1, next.col = cur.col; push(&stack, next);
next.row = cur.row, next.col = cur.col - 1; push(&stack, next);
next.row = cur.row + 1, next.col = cur.col; push(&stack, next);
next.row = cur.row, next.col = cur.col + 1; push(&stack, next);
}
}
// 搜索失败
return 0;
}
int main() {
struct Point start = {1, 1};
struct Point dest = {3, 3};
if (search(start, dest)) {
printf("path found!\n");
} else {
printf("no path found\n");
}
return 0;
}
以上代码通过栈数据结构实现了在迷宫中找出一条从起点到终点的路径。具体实现过程中,我们首先需要定义一个迷宫数组 map
,其中 1
表示墙,0
表示通路 (非障碍物)。is_valid
函数用于判断指定位置是否可通。 相比于递归实现,我们不需要在搜索过程中修改 map
数组的内容,可以避免回溯的操作。计算机先储存起点,再从起点往四周扩散,将四周相邻可走的格子记录下来,然后在这些“待搜元素”中再选择任一元素开始向外扩散,记录在数组中的状态表示该位置已走过(或不能走)。整个过程会保证时间复杂度不会超过迷宫的格子leix ,这样就可以在不超过栈的大小的情况下完成搜索任务。
希望以上示例代码可以帮助你更好地理解迷宫问题的递归和非递归实现,有什么问题请随时联系我!