全排列的几种算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
全排列的⼏种算法
全排列,我们⾼中时就学过,数学上很简单,可是⽤计算机的算法实现还是有点味道的,
今天我将我碰到的⼏种算法如数奉上,欢迎交流!
第⼀种:递归
最常见的也是最好理解的⽅法:
简单点:⽐如"a" ,"b","c"全排列,可以看做事"a" +"b","c"的全排列及"b"+ "a","c"的全排列及"c" + "a","b"的全排列
也就是说,遍历原数组中的每个元素,让剩余的元素全排列,这样就找到规律了。
代码如下:
public static void main(String[] args) {
char buf[]={'a','b','c','d'};
perm(buf,0,buf.length-1);
}
public static void perm(char[] buf,int start,int end){
if(start==end){//当只要求对数组中⼀个字母进⾏全排列时,只要就按该数组输出即可(特殊情况)
for(int i=0;i<=end;i++){
System.out.print(buf[i]);
}
System.out.println();
}
else{//多个字母全排列(普遍情况)
for(int i=start;i<=end;i++){//(让指针start分别指向每⼀个数)
char temp=buf[start];//交换数组第⼀个元素与后续的元素
buf[start]=buf[i];
buf[i]=temp;
perm(buf,start+1,end);//后续元素递归全排列
temp=buf[start];//将交换后的数组还原
buf[start]=buf[i];
buf[i]=temp;
}
}
}
第⼆中⽅法:也是递归,
但是和第⼀种有所区别,
算法:将数据分为两部分,递归将数据从左侧移右侧实现全排列
⽐较抽象,
如list abcd,遍历每⼀个数,将每个数放到⼀个新的list中,并将该元素从原list删除,然后将剩下的元素继续遍历每个元素继续放到新的list ⾥,这样,当list的长度为原list长度,或者原list长度为0时打印结果!
下⾯是简单的⽰意图:
// abcd
//bcd a
//cd ab
//d abc
//abcd
//c abd
//abdc
//bd ac
//d acb
//acbd
//b acd
//acdb
//bc ad ...
//acd b ...
//abd c ...
//abc d ...
源代码如下:
private static void sort(List datas, List target) {
//System.out.println("size="+datas.size());
if (datas.size()==0) {
for (Object obj : target)
System.out.print(obj+" ");
System.out.print(" ");
return;
}
for (int i = 0; i < datas.size(); i++) {
List newDatas = new ArrayList(datas);
List newTarget = new ArrayList(target);
newTarget.add(newDatas.get(i));
newDatas.remove(i);
sort(newDatas, newTarget);
}
}
public static void main(String[] args) {
List list = new ArrayList();
for(int i=0;i<5;i++){
list.add(i+1);
}
sort(list, new ArrayList());
}
第三种⽅法:⾮递归
直接上代码:
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5,6};
for(int i :arr){
System.out.print(i + " ");
}
System.out.println();
int totalnum = 1;
while(NextNumber(arr,arr.length)){
for(int i :arr){
System.out.print(i + " ");
}
System.out.println();
totalnum ++;
}
System.out.println("Total Num: " + totalnum);
}
private static Boolean NextNumber(int[] arr, int n){
//数组最后⼀个元素位置
int lastIndex = n-1;
//从右向左确定第⼀个数字(前⾯的数字⽐它⼩)
int firstIndex = lastIndex;
for(;arr[firstIndex-1]>arr[firstIndex];firstIndex--){
if(firstIndex == 1){
//已经轮询完毕,此数已经是最⼤的那个数
return false;
}
}
//从右向左确定⼀个交换数(此数⽐arr[firstIndex]⼩且⽐arr[firstIndex-1]⼤)int swapIndex = lastIndex;
for(;swapIndex > firstIndex;swapIndex--){
if(arr[swapIndex] < arr[firstIndex] && arr[swapIndex] > arr[firstIndex-1]){
break;
}
}
//交换数字
swap(arr,firstIndex-1,swapIndex);
//将firstIndex右边的数字排序
for(;firstIndex < lastIndex;firstIndex++,lastIndex--){
if(arr[firstIndex] > arr[lastIndex]){
swap(arr,firstIndex,lastIndex);
}
}
return true;
}
private static void swap(int[] arr,int i, int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
如果此⽂对你有帮助,请留个⾔,新⼈需要打架的⽀持和⿎励!。