Python回溯法迷宫生成递归函数终止条件疑问
关于递归迷宫生成代码的终止时机解析
嘿,我来帮你把这段递归代码的终止逻辑掰明白!你提到的这段RosettaCode上的迷宫生成代码,用的是**深度优先搜索(DFS)**的递归实现,虽然没有写显式的return终止语句,但它的终止逻辑藏在访问标记和遍历过程里,咱们一步步拆解:
首先先把完整的代码放出来(补全你给出的片段):
from random import shuffle, randrange def make_maze(w = 16, h = 8): # 标记访问状态的数组,1表示已访问/边界,0表示未访问 vis = [[0] * w + [1] for _ in range(h)] + [[1] * (w + 1)] # 存储垂直墙的结构 ver = [["| "] * w + ['|'] for _ in range(h)] # 存储水平墙的结构 hor = [["+-"] * w + ['+'] for _ in range(h + 1)] def walk(x, y): # 第一步:把当前单元格标记为已访问 vis[y][x] = 1 # 打乱四个方向,保证迷宫的随机性 directions = [(x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)] shuffle(directions) # 遍历所有方向的邻居 for (xx, yy) in directions: # 如果邻居已经被访问过,直接跳过 if vis[yy][xx]: continue # 打通当前单元格和邻居之间的墙 if xx == x: # 垂直方向邻居,修改水平墙 hor[max(y, yy)][x] = "+ " if yy == y: # 水平方向邻居,修改垂直墙 ver[y][max(x, xx)] = " " # 递归探索邻居单元格 walk(xx, yy) # 从随机的一个起始点开始探索 walk(randrange(w), randrange(h)) # 把墙的结构拼接成字符串返回 maze_str = "" for horizontal_wall, vertical_wall in zip(hor, ver): maze_str += ''.join(horizontal_wall) + '\n' maze_str += ''.join(vertical_wall) + '\n' return maze_str print(make_maze())
接下来重点说递归函数walk(x, y)的终止时机:
这个递归没有写if ...: return这种显式终止条件,它的终止是自然发生的,核心依赖两个关键点:
- 第一,
vis数组的访问标记:所有被处理过的单元格都会被标记为1,边界本身也是1,所以未访问的单元格只有值为0的那些。 - 第二,遍历邻居的循环逻辑:
当函数处理某个单元格时,会逐个检查四个方向的邻居。如果邻居已经被访问过(vis[yy][xx] == 1),就直接跳过;如果没被访问过,就打通墙然后递归进去。
当当前单元格的所有四个邻居都已经被访问过时,循环会遍历完所有方向,没有新的递归调用被触发,函数就会执行完所有代码,自动回到上一层递归。
说白了,每一次递归的终止,都是因为当前节点已经没有“未探索的新路径”了——要么是周围全是已经走过的单元格,要么是碰到了迷宫边界。当所有可达的单元格都被标记为已访问后,最顶层的递归也会自然结束,整个迷宫就生成完成了。
举个直观的例子:假设递归走到了一个“死胡同”,四个方向要么是边界,要么已经被走过,那循环里的四个方向都会被if vis[yy][xx]过滤掉,循环结束,walk函数就完成了,回到上一层继续处理其他可能的方向,直到所有路径都被探索完毕。
内容的提问来源于stack exchange,提问作者Rxzlion
相关产品推荐
相关产品推荐

