如何使用回溯打印所有排列?
How to print all permutation using backtracking?
此代码打印 N-1 项的所有排列。但我无法理解一件事:
当 n=N 时,它返回它被调用的地方并使 flag[n-1] = false。因此,i = N-1 并中断循环。但是当 n=N-2 到 0 时,其余排列如何打印或返回?
void perm(int n) {
if (n == N) {
for (int i = 0; i < N ; i++) {
cout<<a[i]<<" ";
}
cout<<endl;
return;
}
for (int i = 0; i < N; i++) {
if (flag[i]) continue;
a[n] = i;
flag[i] = true;
cout<<i<<endl;
perm(n + 1);
cout<<i<<endl;
flag[i] = false;
}
}
您需要考虑函数调用最终是嵌套的。
下面的每个缩进显示一个嵌套调用:
main()
entering perm(0)
entering perm(1)
i = 0
entering perm(2)
let's say N is 2, this will print and return
now perm(1) continues
i becomes 1
entering perm(2)
...
因为 return
只有 returns 来自当前的函数调用,而不是所有函数调用,排列继续打印。
为了熟悉这个,试试这个:
void perm(int n) {
std::cout << "Entering perm " << n << std::endl;
if (n == N) {
for (int i = 0; i < N ; i++) {
cout<<a[i]<<" ";
}
cout<<endl;
std::cout << "Exiting perm " << n << std::endl;
return;
}
for (int i = 0; i < N; i++) {
if (flag[i]) continue;
a[n] = i;
flag[i] = true;
cout<<i<<endl;
std::cout << "about to call perm" << std::endl;
perm(n + 1);
std::cout << "finished call to perm" << std::endl;
cout<<i<<endl;
flag[i] = false;
}
std::cout << "Exiting perm " << n << " (2)"<< std::endl;
}
此代码打印 N-1 项的所有排列。但我无法理解一件事: 当 n=N 时,它返回它被调用的地方并使 flag[n-1] = false。因此,i = N-1 并中断循环。但是当 n=N-2 到 0 时,其余排列如何打印或返回?
void perm(int n) {
if (n == N) {
for (int i = 0; i < N ; i++) {
cout<<a[i]<<" ";
}
cout<<endl;
return;
}
for (int i = 0; i < N; i++) {
if (flag[i]) continue;
a[n] = i;
flag[i] = true;
cout<<i<<endl;
perm(n + 1);
cout<<i<<endl;
flag[i] = false;
}
}
您需要考虑函数调用最终是嵌套的。
下面的每个缩进显示一个嵌套调用:
main()
entering perm(0)
entering perm(1)
i = 0
entering perm(2)
let's say N is 2, this will print and return
now perm(1) continues
i becomes 1
entering perm(2)
...
因为 return
只有 returns 来自当前的函数调用,而不是所有函数调用,排列继续打印。
为了熟悉这个,试试这个:
void perm(int n) {
std::cout << "Entering perm " << n << std::endl;
if (n == N) {
for (int i = 0; i < N ; i++) {
cout<<a[i]<<" ";
}
cout<<endl;
std::cout << "Exiting perm " << n << std::endl;
return;
}
for (int i = 0; i < N; i++) {
if (flag[i]) continue;
a[n] = i;
flag[i] = true;
cout<<i<<endl;
std::cout << "about to call perm" << std::endl;
perm(n + 1);
std::cout << "finished call to perm" << std::endl;
cout<<i<<endl;
flag[i] = false;
}
std::cout << "Exiting perm " << n << " (2)"<< std::endl;
}