1. 全排列
思路1:递归分治(基于交换)
#include <stdio.h> void perm(int* a, int start, int end); void swap(int& m, int& n); void output(const int* a, int size); int main() { int a[5] = {1, 2, 3, 4, 5}; perm(a, 0, 5); return 0; } void perm(int* a, int start, int end) { if(start == end - 1) { output(a, end); } else { for(int i = start; i < end; ++i) { swap(a[start], a[i]); perm(a, start + 1, end); swap(a[start], a[i]); } } } void swap(int& m, int& n) { int t = m; m = n; n = t; } void output(const int* a, int size) { static int count; printf("%3d: ", ++count); for(int i = 0; i < size; ++i) { printf("%d ", a[i]); } printf("\n"); }
思路2:剪枝回溯
#include <stdio.h> void perm(int* data, int* buf, int start, int end); void output(const int* a, int size); int main() { int data[5] = {1, 2, 3, 4, 5}; int buf[5] = {0}; perm(data, buf, 0, 5); return 0; } void perm(int* data, int* buf, int start, int end) { if(start == end) { output(buf, end); } else { for(int i = 0; i < end; i++) { if(!data[i]) continue; buf[start] = data[i]; data[i] = 0; perm(data, buf, start + 1, end); data[i] = buf[start]; } } } void output(const int* a, int size) { static int count; printf("%3d: ", ++count); for(int i = 0; i < size; ++i) { printf("%d ", a[i]); } printf("\n"); }
2. 汉诺塔
#include <stdio.h> void hanoi(int n, char a, char b, char c); void move(int n, char from, char to); int main() { hanoi(5, 'A', 'B', 'C'); return 0; } void hanoi(int n, char a, char b, char c) { if(n > 0) { hanoi(n - 1, a, c, b); move(n, a, b); hanoi(n - 1, c, b, a); } } void move(int n, char from, char to) { static int step; printf("Step %3d: No.%d %c -> %c.\n", ++step, n, from, to); }