递归算法recursion

1 简论

当一个函数用它自己来定义时就称为递归的。
要素:

  • 基准情况:初始值,不用递归就能求解。
  • 递归推进:朝着产生基准情形的方向推进。
  • 特殊情况:函数内部对输入参数定界。
  • 设计法则:假设所有递归调用都能运行。
  • 合成效益法则:求解同一问题同一实例,不能做重复性工作。

2 实例

2.1 最大和连续子序列

给定一个整数序列,a0, a1, a2, …… , an(项可以为负数),求其中最大的子序列和。如果所有整数都是负数,那么最大子序列和为0;
用到了递归,用到了这样一种思想,当然要我肯定想不到,纯属借鉴了:

对于一数字序列,其最大连续子序列和对应的子序列可能出现在三个地方。或是整个出现在输入数据的前半部(左),或是整个出现在输入数据的后半部(右),或是跨越输入数据的中部从而占据左右两半部分。前两种情况可以通过递归求解,第三种情况可以通过求出前半部分的最大和(包含前半部分的最后一个元素)以及后半部分的最大和(包含后半部分的第一个元素)而得到,然后将这两个和加在一起即可

主要从递归的角度分析,把问题分为了小问题【分治法的策略】,处理的过程都一样,然后递归。—过程和终点。

首先分析终点,子问题一步步被划分,最终,明显看出,原始序列最终会被分为一个长度为1的子序列(一个大于1的数一直除,肯定会到1的),把长度为1的子序列当成原问题,那么根据题意,如果是正数,就要,如果是负数,不如不要,就为0。所以,递归的终点设置得正确。
然后分析过程,分析递归的过程,在debug的过程中,你能发现,递归最开始是一直拆分子问题,直到到达递归终点再一层一层倒着返回调用结果。可以把递归过程看成一个二叉树,所以递归终点就是此递归过程二叉树的最后一层,而在以下程序中, MaxLeftSum = MaxSubSum(A,Left,Center); 这句就是左孩子,MaxRightSum = MaxSubSum(A,Center+1,Right);就是右孩子。而左孩子语句先执行,所以过程最开始一定是往左下方向直到第一个终点,再把他们左右序列最大值(因为两序列各只有一个,且这里必须包含左序列最右和右序列最左,所以这里就是这俩序列自身)加起来。

int MaxSubSum( int A[], int Left, int Right)  
	{  
	    int MaxLeftSum,MaxRightSum;  
	    int MaxLeftBorderSum,MaxRightBorderSum;  
	    int LeftBorderSum,RightBorderSum;  
	    int Center,i;  
	      
	    if(Left == Right)  
	    {  
	        if(A[Left] > 0)  
	            return A[Left];  
	        else  
	            return 0;  
	    }  
	      
	    Center = (Left + Right)/2;  
	    MaxLeftSum = MaxSubSum(A,Left,Center);  
	    MaxRightSum = MaxSubSum(A,Center+1,Right);  
	      
	    MaxLeftBorderSum = 0;  
	    LeftBorderSum = 0;  
	    for(i = Center;i >= Left;i--)  
	    {  
	        LeftBorderSum += A[i];  
	        if(LeftBorderSum > MaxLeftBorderSum)  
	            MaxLeftBorderSum = LeftBorderSum;  
	    }  
	      
	    MaxRightBorderSum = 0;  
	    RightBorderSum = 0;  
	    for(i = Center+1;i <= Right;i++)  
	    {  
	        RightBorderSum += A[i];  
	        if(RightBorderSum > MaxRightBorderSum)  
	            MaxRightBorderSum = RightBorderSum;  
	    }     
	      
	    return Max(MaxLeftSum,MaxRightSum,MaxLeftBorderSum + MaxRightBorderSum);  
	}   
	  
static int Max(int a, int b, int c)  
{  
    if(a>b&&a>c)  
        return a;  
    else if(b>a&&b>c)  
        return b;  
    else  
        return c;   
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值