递归的应用

1. 设计一个算法并编程实现,将一个正整数划分成多个正整数的加和,并把所有的结果组合输出。

分  析: 正整数的划分就是把一个正整数n,写成多个大于等于1且小于等于其本身的整数的和,其中各加数所构成的集合为n的一个划分,这是一个典型的递归算法。即:

 一个正整数被划分成多个正整数,划分组合的成员个数最多是这个正整数的大小,最少是这个正整数本身。而且在递归的过程中还要传递上层的划分数字,要求划分的后一个数字大于等于前一个,使无序的划分方式变为有序,去掉重复项。

代码实现: 

#include <stdio.h>
int mark[10]; //定义全局变量 
int n;
void Divide(int now,int k,int pre){
   int i;
   if(now>n) return;
   if(now==n){
        for(i=0;i<k-1;i++)
          printf("%d+",mark[i]);
    printf("%d\n",mark[i]);
   }
   else{
     for(i=pre;i>0;i--){
        if(i<=pre){
           mark[k]=i;
           now+=i;
           Divide(now,k+1,i); //递归调用函数 
           now-=i;
        }
     }
   }

int main(void){
   scanf("%d",&n);
   Divide(0,0,n-1);
   return 0;
}

运行结果

 

2. 设计一个算法并编程实现,对一组数的全排列,并将所有的排列结果输出。

分 析 :   对于全排列问题,f(n)=n!(定义0!=1),其中需要用到函数的递归调用,在调用中,序列中的某两个元素需要不断地交换位置,在输出时调用一次,满足条件即可输出,是一种情况。一组数的全排列组合的个数为n!,通过先序递归将这一组数存入新的数组中,递归的过程中需要判断新放入的数在数组中是不是存在,如果存在,就不能被放入数组中,如果不存在,则可以放入数组,递归一次,在数组中放入一个数。递归四次则输出一次,输出完成后递归回退,进行穷举。R的全排列可归纳定义如下:

当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素;

当n>1时,Perm(R)由(r1)Perm(R1),(r2)Perm(R2),......,(rn)Perm(Rn)构成。

代码实现

#include <stdio.h>  
#define N 100
void swap(int *a, int *b){     //功能:交换两个数
    int m;     
     m = *a;     
    *a = *b;     
    *b = m;
}  
void perm(int arr[], int k, int m){     
    int i,n=0;     
    if(k > m){         
        for(i = 0; i <= m; i++)            
            printf("%d ", arr[i]);         
        printf("\n");         
        n++;     
    }     
    else{         
        for(i = k; i <= m; i++){            
            swap(&arr[k], &arr[i]);            
            perm(arr, k + 1, m);    //递归调用        
            swap(&arr[k], &arr[i]);         
        }     
    }
}
int main(void){     
    int n,i,k;
    int arr[N];
    printf("请输入有几个数:\t");
    scanf("%d",&n);
    for(i = 0; i < n; i++)  {
        scanf("%d", &arr[i]);
    }
    perm(arr, 0, n-1);         
    return 0;

运行结果

转载于:https://my.oschina.net/xieganying/blog/791646

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值