昨晚心血来潮,想起全排列算法,但是忘记怎么实现,所以就自己再次试图编写代码实现。
晚上想不出来,想不到,一觉醒来后,一下子就写好了!
public class QuanPailie {
/** 统计总数 */
static int total = 0;
/** allRank调用次数 */
static int call = 0;
public static void swap(int[] array, int a, int b) {
if (a == b) {
return;
}
array[a] = array[a] ^ array[b];
array[b] = array[a] ^ array[b];
array[a] = array[a] ^ array[b];
}
public static void print(int[] array) {
for (int element : array) {
System.out.print(element + " ");
}
System.out.println();
total++;
}
/**
* 数组第一个元素固定,<br>
* 其他后续的元素再allRank(array, begin + 1, length); <br>
* (当然,还需要轮流让每个元素放在第一位)
*
* @param array
* @param begin
* @param length
*/
public static void allRank(int[] array, int begin, int length) {
call++;
if (begin == length - 1) {
// 每个递归的最后,是打印输出
print(array);
} else {
for (int i = begin; i < length; i++) {
// 使用for(int i = begin; i < length; i++)去轮流放在第一位
swap(array, begin, i);
// 无视第一位,将后续的元素继续递归
allRank(array, begin + 1, length);
// 如果不恢复现场,那么allRank就是一个会改变array的函数,那么
// 使用“for(int i = begin; i < length; i++)去轮流放在第一位的做法”
// 就会失效。
swap(array, i, begin);
}
}
}
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5 };
allRank(array, 0, 5);
System.out.println("不同顺序的总数(5!):" + total + "\n allRank()被调用的总数:" + call);
}
}
输出:
不同顺序的总数(5!):120
allRank()被调用的总数:206
以下补充于20101204:
PS:对于圆形(或头尾相连的数组)的全排列算法 ,只要把其中一个数(就选第一个数吧)固定(而不是轮流选择一个数放在第一位),剩下的n-1个数进行全排列,即可,总数是(N-1)! = N! / N 。感谢ACM牛人傻涛的帮助!