第七期:实现一个算法求某集合的全排列(递归交换法)
题目分析:以集合a={A,B,C,D,E}为例
A | B | C | D | E |
---|
第一步: 我们以第一个元素 A 开始进行与后面的元素进行交换,递归下去。即 A 和 BCDE 中的任何一个元素进行交换。
第二步:对于 BCDE , 我们利用递归的思想,利用当前的第一个元素 B 开始进行与后面的元素进行交换。即 B 和 CDE 中的任何一个元素进行交换。
第三步:对于 CDE , 我们利用递归的思想,利用当前的第一个元素 C 开始进行与后面的元素进行交换。即 C 和 DE 中的任何一个元素进行交换。
第四步:对于 DE , 我们利用递归的思想,利用当前的第一个元素 D 开始进行与后面的元素进行交换。即 D 和 E 元素进行交换。
得到其中的一种全排列方式的结果是:
A | B | C | E | D |
---|
第五步:上一次交换后得到的结果,我们需要还原现场,即回溯。
Java代码:
/**
* 全排列问题
* abc三个元素的全排列。
* abc acb bac bca cab cba
*/
public class Permutation2 {
public static void main(String[] args) {
char[] data = "abc".toCharArray();
f(data, 0);
}
/**
* 第0个元素与之后的每个元素交换
* 第1个元素与之后的每个元素交换
* ....
* @param data
* @param k: 当前的交换位置(关注点),与其后的元素交换
*/
private static void f(char[] data, int k) {
// 自己带出口,不需要再次写出口。
if (k==data.length-1){
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]+" ");
}
System.out.println();
}
for (int i = k; i < data.length; i++) {
//试探交换
{
char temp = data[k];
data[k] = data[i];
data[i] = temp;
}
f(data, k + 1);
//回溯交换
{
char temp = data[k];
data[k] = data[i];
data[i] = temp;
}
}
}
}
简要分析:
挑战:递归的效率不高,有待改进。