现在的位置: 首页 > 综合 > 正文

两个古老问题的递归算法。

2013年08月08日 ⁄ 综合 ⁄ 共 1306字 ⁄ 字号 评论关闭

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);
}

抱歉!评论已关闭.