您的位置:首页 > 其它

全排列算法(字典序,递归实现)

2014-09-14 22:18 381 查看
字典序算法如下:

设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn

1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}<br/>

2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即k=max{i|pi>pj}(右边的数从右至左是递增的,

因此k是所有大于pj的数字中序号最大者)<br/>

3)对换pi,pk<br/>

4)再将pj+1......pk-1pkpk

+1pn倒转得到排列p''=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个下一个排列。

例如839647521是数字1~9的一个排列。从它生成下一个排列的步骤如下: 自右至左找出排列中第一个比右边数字小的数字4 839647521

在该数字后的数字中找出比4大的数中最小的一个5 839647521 将5与4交换 839657421 将7421倒转 839651247

所以839647521的下一个排列是839651247。 839651247的下一个排列是839651274。

public static void main(String[] args) {
long l1 = System.currentTimeMillis();
System.out.println("请输入要对前n个数字进行排列:");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int[] arry = new int
;
for (int i = 0; i < arry.length; i++) {
arry[i] = i + 1;
}
System.out.println(Arrays.toString(getInt(arry)));
do {
System.out.println(Arrays.toString(getInt(arry)));
} while (next(arry));
long l2 = System.currentTimeMillis();
System.out.print("共耗时" + (l2 - l1) + "耗秒");
}

private static int[] getInt(int[] arry) {
int[] arry1 = new int[arry.length];
System.arraycopy(arry, 0, arry1, 0, arry.length);
return arry1;
}

private static boolean next(int[] arry) {
int pos1 = -1;
int pos2 = -1;
//从右到左,找到第一个比右边小的数,记录位置pos1
for (int i = arry.length - 1; i > 0; i--) {
if (arry[i - 1] < arry[i]) {
pos1 = i - 1;
break;
}
}
if (pos1 < 0) {
return false;
}
//在pos1位置后的数字中找出比它大的数中最小的一个,然后交换位置,在逆转
for (int i = arry.length - 1; i > pos1; i--) {
if (arry[i] > arry[pos1]) {
pos2 = i;
swap(arry, pos2, pos1);
reserve(arry, pos1 + 1, arry.length - 1);
break;
}
}
if (pos2 < 0) {
return false;
}
return true;
}

/**
*
* 逆转数组中第i个到第j个的数,比如数组为123,i=0,j=2,则逆转为321
*
* @param arry
* @param i
* @param j
*/
private static void reserve(int[] arry, int i, int j) {
for (; i <= j; i++, j--) {
swap(arry, i, j);
}
}

/**
* 交换一个数组中第i个和第j个数的值
*
* @param array
* @param i
* @param j
*/
private static void swap(int[] array, int i, int j) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}


全排列递归算法实现

如果集合是{a,b,c},那么这个集合中元素的所有排列是{(a,b,c),(a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)},显然,给定n个元素共有n!种不同的排列,如果给定集合是{a,b,c,d},可以用下面给出的简单算法产生其所有排列,即集合(a,b,c,d)的所有排列有下面的排列组成:

(1)以a开头后面跟着(b,c,d)的排列

(2)以b开头后面跟着(a,c,d)的排列

(3)以c开头后面跟着(a,b,d)的排列

(4)以d开头后面跟着(a,b,c)的排列,这显然是一种递归的思路,于是我们得到了以下的实现:

public static void main(String[] args) {
char[] data={'a','b','c'};
permutation(data,0,data.length-1);
}

private static void permutation(char[] data, int start, int end) {
int i,j;
if(start==end){
for(i=0;i<=end;i++){
System.out.print(data[i]);
}
System.out.println();
}else{
for(j=start;j<=end;j++){
swap(data,j,start);
permutation(data, start+1, end);
swap(data,j,start);
}
}
}

private static void swap(char[] data,int j, int start) {
char temp = data[j];
data[j] = data[start];
data[start] =temp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: