问题:从不同元素中任取m(m<=n)个元素,按照一定的顺序排列起来 ,叫做从n 个不同元素中取出m个元素的一个排列。 当m = n 是所有的排列情况较全排列。
如 1 , 2 , 3 的全排列如下
1 , 2 ,3
1 ,3 , 2
2 ,1 ,3
2 ,3 ,1
3, 1 ,2
3, 2 ,1
当 n = 1 ; 全排列 就是这个数字;
当 n>1 , 全排列为 { (1)p1 , (2) p2 , (3)p3,(4)p4 }, 其中p1= {2,3,4)的全排列 ,p2 = {1,3,4}的全排列 , p3 = {1,2,4}的全排列 , p4 = {1,2,3}的全排列
而p1 , p2 , p3 , p4 的是用a1分别于第一个,第二个,第三个,直到第n个元素交换之后得到序列的最后三个元素。
这样求n个元素的全排列变成求n次n-1个元素的全排列问题,规模缩小。
代码如下
#include<stdio.h>
void swap(int *p ,int *q)
{
int t = *p;
*p = *q;
*q = t;
}
void perm(int a[],int k, int m)
{
int i;
if(k==m)
{
for(i = 0;i<=m;i++)
{
printf("%d",a[i]);
}
printf("\n");
}
else
{
for(i = k;i<=m;i++)
{
swap(&a[k],&a[i]);
perm(a,k+1,m);
swap(&a[k],&a[i]);
}
}
}
int main()
{
int i , n , a[10];
scanf("%d",&n);
for(i = 0;i<n;i++)
scanf("%d",&a[i]);
perm(a,0,n-1);
return 0;
}
全排列输出时候是无序的
比如 在求第n-1个元素的时候 交换后的元素序列变成 n-1 , 2, 3 ,4 ,5 ,6 ,...........n-3, n-2 , 1 , n
此时序列不是有序的 应该变成 n-1 ,1 , 2 ,3 , 4 ,5 ,6 .........,n-4, n-3 ,n-2 ,n
解决优化之后
#include<stdio.h>
void swap(int *p ,int *q)
{
int t = *p;
*p = *q;
*q = t;
}
void circular_right(int a[],int left,int right)
{
int t ,i ;
if(left>=right)
return ;
t = a[right];
for(i = right;i>left;i--)
a[i] = a[i-1];
a[left] = t;
}
void circular_left(int a[],int left,int right)
{
int t, i ;
if(left>=right)
return ;
t = a[left];
for(i = left;i<right;i++)
a[i] = a[i+1];
a[right] = t;
}
void perm(int a[],int k, int m)
{
int i;
if(k==m)
{
for(i = 0;i<=m;i++)
{
printf("%d",a[i]);
}
printf("\n");
}
else
{
for(i = k;i<=m;i++)
{
swap(&a[k],&a[i]);
circular_right(a,k+1,i);
perm(a,k+1,m);
circular_left(a,k+1,i);
swap(&a[k],&a[i]);
}
}
}
int main()
{
int i , n , a[10];
scanf("%d",&n);
for(i = 0;i<n;i++)
scanf("%d",&a[i]);
perm(a,0,n-1);
return 0;
}