排列组合问题是一个运用递归的经典问题,我每次看到递归,脑袋就大,可是问题还是没办法逃避的,因此,认真学习一下关于排列组合问题的解法。
组合问题:
抽象描述:
总共有n个物体(在这里以数字1~n表示n个物体),选取r个物体,输出其排列顺序,以及个数。
算法描述:
- 我们从升序进行输出;因此最大的元素A的范围:r~n;
- 对于A(最大元素),考虑n,所有的序列可以被分成为两块:有n(n-r,r-1)和无n(n-1,r);
- 对于有n的情况,继续考虑n-1的情况; 对于无n的情况,继续考虑n-1的情况; 终止条件:n=r与n=0的情况;(如果n=r,那么剩下的元素只能是一一对应;如果n=1,那么直接输出序列)
代码描述:
#include<stdio.h>
#include<stdlib.h>
//n:剩余元素 r:待选元素个数
void DFS(int result[],int n,int r,int L,int* times){
if(n==r){
for(int i=0;i<r;i++){
result[i]=i+1;
}
for(int j=0;j<L;j++){
printf("%d ",result[j]);
}
printf("\n");
(*times)++;
return ;
}
else if(r==0){
for(int i=0;i<L;i++){
printf("%d ",result[i]);
}
printf("\n");
(*times)++;
return ;
}
else{
result[r-1]=n; //选中n的情况
DFS(result,n-1,r-1,L,times); //分两种情况进行考虑!
DFS(result,n-1,r,L,times);
}
}
void main(){
int n; //总物体数目
int r; //挑选物体数目
int i; //r~n:构成所有的情况
int times=0;
printf("请输入总物体的数目:");
scanf("%d",&n);
printf("请输入挑选物体的数目:");
scanf("%d",&r);
int result[r]; //记录路径
int L=r; //为result[]记录数组长度
DFS(result,n,r,L,×); //既要包含选择n的情况,也包含无n的情况;那么分为多层;通过回溯,递归。
printf("所有情况的数目为: %d\n",times);
}