全排列算法
题目描述
对于一个给定的序列 a = [a1, a2, a3, … , an],请设计一个算法,用于输出这个序列的全部排列方式。
解题思路
1.当N=1时,打印a[0],的全排列
2.当N=2时,
第一步:把a[0]放在首位,打印a[1]=的全排列
第二步:把a[1]放在a[0]的位置(这时候需要交换原数组的a[0]和a[1]),然后打印a[0],a[2]的全排列,打印完后再换回原来的位置
3.当N=3时,
第一步:把a[0]放在a[0]的位置,打印a[1],a[2]的全排列(即a[1], a[2]的全排列)
第二步:把a[1]放在a[0]的位置(这时候需要交换原数组的a[0]和a[1]),然后打印a[0],a[2]的全排列,打印完后再换回原来的位置
第三步:把a[2]放在a[0]的位置(这时候需要交换的是原数组的a[0]和a[2]),然后打印a[0],a[1]的全排列,打印完后再换回原来的位置
4.当N = 4,5,6,……的时候,以此类推。
具体代码实现
#include <stdio.h>
#include <stdlib.h>
#define ElemType char
//#define N 3
int Count=0;
int isRep(ElemType a[],int start,int i){ //判断从start-->i中有没有与i相同的元素,如果有证明i是重复的
for(int k=start;k<i;k++){
if(a[k]==a[i])
return false;
}
return true;
}
void Swap(ElemType a[],int i,int j){
ElemType temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
void Arithmetic(ElemType a[],int start,int end){ //全排列
if(start==end-1){ //最后一个元素不用交换自身
Count++;
printf("第%2d种排列:",Count);
for(int i=0;i<end;i++){
printf("%c ",a[i]);
}
printf("\n");
}
else{
for(int i=start;i<end;i++){
if(isRep(a,start,i)){ //如果从start-->i没有与i相同的元素则交换
Swap(a,start,i); //交换start<-->i 进行递归
Arithmetic(a,start+1,end);
Swap(a,start,i); //用完之后再交换回来
}
}
}
}
int main(){
// ElemType a[N]={1,2,2};
int N;
printf("请输入数组长度:");
scanf("%d",&N);
getchar(); //当ElemType为char时使用
ElemType *a=(ElemType *)malloc(N*sizeof(ElemType));
printf("请输入数组元素:");
for(int i=0;i<N;i++)
scanf("%c",&a[i]);
printf("全排列:\n");
Arithmetic(a,0,N);
printf("\n共%d种排列方式\n",Count);
return 0;
}