递归专题
1、求n个数的子序列
设这n个数为1,2,3
则为子序列如下:

恰好构成一个满二叉树
则只需深度遍历满二叉树,访问时把路径记录下来即可

1 #include <stdio.h> 2 #include <stdlib.h> 3 #define MAXN 20 4 5 int path[MAXN];//记录沿途选择的数字 6 int select(int a[],int pos,int n,int count){ 7 int i; 8 if(pos>=n){ 9 for(i=0;i<count;i++) 10 printf("%d ",path[i]); 11 printf("\n"); 12 return ; 13 } 14 15 path[count]=a[pos]; 16 select(a,pos+1,n,count+1);//当走到索引为pos时,记录下来 17 18 select(a,pos+1,n,count);//当走到索引为pos时,不记录 19 20 21 } 22 23 int main() 24 { 25 int a[]={1,2,3}; 26 select(a,0,sizeof(a)/sizeof(int),0); 27 return 0; 28 }
运行结果如下:

2、在1问题的基础上变化一下,问题为:在n个数中取m个数,有多少种情况?
只需对count进行判断判断就行:

1 #include <stdio.h> 2 #include <stdlib.h> 3 #define MAXN 20 4 #define M 2 5 int path[MAXN];//记录沿途选择的数字 6 int sum=0; 7 int select(int a[],int pos,int n,int count){ 8 int i; 9 if(pos>=n){ 10 if(count==M){ 11 for(i=0;i<count;i++) 12 printf("%d ",path[i]); 13 printf("\n"); 14 sum++; 15 } 16 return ; 17 } 18 19 path[count]=a[pos]; 20 select(a,pos+1,n,count+1);//当走到索引为pos时,记录下来 21 22 select(a,pos+1,n,count);//当走到索引为pos时,不记录 23 24 25 } 26 27 int main() 28 { 29 int a[]={1,2,3,4}; 30 select(a,0,sizeof(a)/sizeof(int),0); 31 printf("sum=%d\n",sum); 32 return 0; 33 }
运行结果如下:

3、有n本书,选m本使得这m本书的价格之和为S (m能的值为1,2,3,...,n)

1 #include <stdio.h> 2 #include <stdlib.h> 3 #define MAXN 31 4 5 6 typedef struct book{ 7 char name[20]; 8 int price; 9 }BOOK; 10 11 typedef struct stack{ 12 int top; 13 BOOK booklist[MAXN]; 14 }BOOKSTACK; 15 16 void sortbook(BOOK *books,int n); 17 void selectbook(BOOK *books,int pos,int n,int top,int sum); 18 BOOK Findcon(BOOK *books,int price,int n);//在books中查找出价格为x的书籍,并且返回这本书 19 20 void Push_stack(BOOKSTACK* package,BOOK a_book,int *top ); 21 int S,N;//带了S元 在N本中选取M本 22 int choice=1; 23 BOOKSTACK packge;//用于存放选择的书 24 FILE *in,*out; 25 int main() 26 { 27 28 BOOK books[MAXN]; 29 30 int i; 31 if((in=fopen("data.txt","r"))==NULL){ 32 printf("Cannot open the %s.\n","data.txt"); 33 exit(0); 34 } 35 36 if((out=fopen("result.txt","w"))==NULL){ 37 printf("Cannot open the %s.\n","result.txt"); 38 exit(0); 39 } 40 41 fscanf(in,"%d%d",&S,&N); 42 43 for(i=0;i<N;i++) 44 fscanf(in,"%s%d",books[i].name,&books[i].price); 45 46 for(i=0;i<N;i++) 47 printf("%s%4d\n",books[i].name,books[i].price); 48 sortbook(books,N); 49 selectbook(books,0,N,0,0); 50 51 printf("Finshed!\nThe results are displayed in \"result.txt\" .\n"); 52 return 0; 53 } 54 55 void selectbook(BOOK *books,int pos,int n,int top,int sum){ 56 57 if(pos>=n||sum>=S){ 58 if(sum==S){ 59 packge.top=top; 60 fprintf(out,"\nChoice[%d]:\n",choice++); 61 Print(packge); 62 } 63 return ; 64 } 65 packge.booklist[top]=books[pos]; 66 selectbook(books,pos+1,n,top+1,sum+books[pos].price); 67 selectbook(books,pos+1,n,top,sum); 68 69 } 70 71 72 void Print(BOOKSTACK packge){ 73 int i; 74 int len=packge.top; 75 for(i=0;i<len;i++){ 76 fprintf(out,"Book name:%s -- Price:%d\n",packge.booklist[i].name,packge.booklist[i].price); 77 } 78 fprintf(out,"\n"); 79 } 80 81 void sortbook(BOOK *books,int n){ 82 int i,j,t;//用选择排序法从大到小排 83 BOOK temp; 84 for(i=0;i<n-1;i++){ 85 t=i; 86 for(j=i+1;j<n;j++){ 87 if(books[t].price<books[j].price) 88 t=j; 89 } 90 if(t!=i){ 91 temp=books[i]; 92 books[i]=books[t]; 93 books[t]=temp; 94 } 95 96 } 97 }