以这个为例:
bool SolveSudoku(int grid[N][N]){ int row, col; // 如果没有未分配的位置,我们就完成了 if (!FindUnassignedLocation(grid, row, col)) return true; // 成功! // 考虑数字1到9 for (int num = 1; num <= 9; num++) { // 如果看起来有希望 if (isSafe(grid, row, col, num)) { // 尝试分配 grid[row][col] = num; // 如果成功,返回,耶! if (SolveSudoku(grid)) return true; // 失败,撤销并重试 grid[row][col] = UNASSIGNED; } } return false; // 这会触发回溯}
网格总是作为参数传递给递归调用,因此在每次迭代中都会有一个新的网格副本。
我似乎无法理解使用全局网格和使用相同逻辑有什么区别。
在失败条件之后,变量被设置为“撤销并重试”——这不应该处理回溯中的任何“撤销”吗?
如果网格是一个全局变量,这个递归回溯会有什么不同,为什么每次都要发送一个额外的副本?
回答:
网格总是作为参数传递给递归调用,因此在每次迭代中都会有一个新的网格副本。
不,每次迭代中有一个新的网格引用(指针)的副本。实际的工作是在同一个网格上反复进行的。
例如,看看这个代码片段:
#include <stdlib.h>#include <stdio.h>void foo(int arr[], int n) { arr[0] = 1;}int main() { int myArray[5] = {0,0,0,0,0}; foo(myArray,5); printf("%d",myArray[0]); return 0;}
请注意,没有创建副本,对foo()
中arr
的更改反映到了myArray
上。
一旦明白了这一点,我相信它会自动回答你其余的问题(这基本上与使用全局变量相同,但全局变量通常是不好的做法,发送数组的引用是更好的做法)。