类循环组合排序: 有M个数 每个数有N种可能
如:4 2 0000 0001 0010 0011 0100.....1110 1111
利用递归的思想:
可以把它现象成一颗树:一颗子树数相同的数:
由于每一层有做相同的子树所以再递归函数中有
for(int i;i
循环代表递归函数中有多少个子树是要用到调用自身函数的即用for来实现多个有N个
在每个子树中的情况都一样,自是它的层数I+1了,由于有M个数所以它是有M-1层的
所以它的出口时:I>M,就把mat[i]输出来
void solve(int l){
if(l>=n){
for(int i=0;i<n;++i)printf("%d", mat[i]);
puts("");
return;
}
for(int i=0;i<m;++i){
mat[l]=i;
solve(l+1);
}
}
if(l>=n){
for(int i=0;i<n;++i)printf("%d", mat[i]);
puts("");
return;
}
for(int i=0;i<m;++i){
mat[l]=i;
solve(l+1);
}
}
solve(0);//函数调用,是代表从第一层开始
全组合排序:这个和上一个有一点不同那就是子树的点不能和父点相同,即一个分支的组合数不能相同
只要在for(i<0;i
if(!used[i]){//是个标记为了把上层已经用过的点去除掉
used[i]=1;
num[I]=mat[i];//mat为输入的数;num为输出的数;
solve(I+1);//下一层;了
used[i]=0;//代表一个分支对另一个分支不影响,所以要初始化回来;
}
}
非重复组合排序(含有重复数字时,生成不重复组合排序)
只要为重复的数当成一个数来处理,但是这个数可以用多次每次用完即减一就可以了,其它的和全组合是一样的。
普通选择性排序:它是在M个数中选N个数进行完全排列 如数学中的C(N,M)
#include
#include
#include
void conbination(int I,int start);
int m,n;
int *in,*out;
void conbination(int I,int start){//I代表层数 start代表一层从哪个数开始
int j,i;
if(I>=n){//当到了第N层时是出口
for(j=0;j
printf("\n");
return;
}
for(i=start;i<=m-n+I;i++){ //start一层中第一个数,m-n+I代表一层中最后一个数
out[I]=in[i];//把的到的数赋值给输出
conbination(I+1,i+1);//下一层,并且是从上次的开始下一位作为开始进行递归了。
}
}
void main(){
int i;
scanf("%d,%d",&m,&n);
in=(int *)malloc(sizeof(int)*m);
out=(int *)malloc(sizeof(int)*m);
for(i=0;i
scanf("%d",&in[i]);
memset(out,0,sizeof(int)*m);
conbination(0,0);
free(in);
free(out);
}
//今天总结到这,下次有空再继续