下列代码试图打印数字1-9的全排列组合。
#include "stdio.h" #define N 9 int x[N]; int count = 0; void dump() { int i = 0; for (i = 0; i < N; i++) { printf("%d", x[i]); } printf("\n"); } void swap(int a, int b) { int t = x[a]; x[a] = x[b]; x[b] = t; } void run(int n) { int i; if (N - 1 == n) { dump(); count ++; return; } for (i = ___; i < N; i++) { swap(___, i); run(n + 1); swap(___, i); } } int main() { int i; for (i = 0; i < N; i++) { x[i] = i + 1; } run(0); printf("* Total: %d\n", count); }
其中run函数中缺失的部分应该依次为:
这是一道分治算法题。这种循环套递归的题目是很难一下子理解的,因此可以把问题的规模减小。先试 3 个元素,然后我们发现,在循环里面第一句话是那当前的某个数和后面的某个数交换(包括和自己交换,也就是不交换),交换完了之后,后面那个递归就是分治了,也就是从待交换的数的下一个开始直到末尾的一段调用递归用分治搞定。分治一直调用到最后无法交换的时候,也就是末尾两个指针相遇的时候程序就输出一种排列。所以在递归退出之后,根据程序的逻辑,在当前层循环里面应该只负责当前数和后面的数的交换,而当前数不能变,所以要把现场恢复,因此还需要调用一次 swap 再交换回来就可以了。所以根据程序逻辑,应该选择 C 。自己画一个三个数的排列就可以看明白了, 9 个数太复杂,搞明白关系就可以了。