递归

方法归纳

判断是否为递归问题

取决于是否每次执行的是相同的工作起到相同的功能
例如汉诺塔中的每次n个碟子移动时,总是需要先将n-1个碟子移到中间碟子中
可以用一般式n表示该问题

总结

1.结束时的条件
2.分析一层递归需要实现的功能
3.返回值是如何,传送给上一级的信息

汉诺塔


#include< iostream>
using namespace std;
void  hanoi(int n, char one, char two, char three);
//one是原始柱,two是中间柱子,three是结尾柱
void move(char x,char y);
void move(char x, char y)//输出
{
    cout << x << "->" << y << endl;
}
void  hanoi(int n,char one,char two,char three)
{
    if (n == 1)
        move(one, three);
    else
    {
        hanoi(n - 1, one,three,two);
        move(one, three);
        //每次执行的操作
        hanoi(n - 1, two, one, three);
    }
}
int main()
{
    int n;
    scanf("%d", &n);
    char one = '1', two = '2', three = '3';
    hanoi(n, one, two, three);
    return 0;
}

汉诺塔问题分析与总结

1.< 判断是否递归>模拟汉诺塔移动,因为大的总在小的下面,所以当最大的碟子放在C上时,n-1个在C上,这时可以忽略这个这个最大的碟子,也就是把问题看成n-1个碟子从B柱子移动到C柱子(A为原始柱,B为中间柱,C为目标柱),所以这个是一个递归问题(每次都需要将n-1个碟子送到中间柱子上)
2.< 结束操作与条件>
分析n-1的终点是什么?必定是只剩一个碟子(这里可以用极限n=1)
3.< 每层执行的功能>
即执行从A上移动n-1个碟子到B上,再将A最大碟子移动到C上,再将B上n-1个碟子移到C上

二分法求数组最大子序列


#include< iostream>
#include< cstdlib>//malloc
using namespace std;
int Maxnumber(int x, int y, int z)//判断最大的值
{
    return x > y ? x > z ? x : z : y > z ? y : z;
}
int Max(int arry[], int left, int right)
{
    if (left == right)
        return arry[left];
    int center = (left + right)/2;
    int Tempsum=0,Maxleftsum=0,Maxrightsum=0;
    //求出从中间点向左右衍生的最大子序列值
    for (int x = center; x >= left; x--)
    {
        Tempsum += arry[x];
        Maxleftsum = Tempsum > Maxleftsum ? Tempsum : Maxleftsum;
    }
    Tempsum = 0;
    for (int x = center + 1; x <= right; x++)
    {
        Tempsum += arry[x];
        Maxrightsum = Tempsum > Maxrightsum ? Tempsum : Maxrightsum;
    }
    return Maxnumber(Maxrightsum + Maxleftsum, Max(arry, left, center), Max(arry, center + 1, right));
    //只需要比较左边最大值,右边最大值和从中间开始的最大值
}
int main()
{
    int* arry, x,Maxsum=0,Tempsum=0;
    cin >> x;
    arry = (int*)malloc(x * sizeof(int));//动态数组
    for (int y=0; y <= x - 1; y++)
        cin >> arry[y];
    Maxsum = Max(arry, 0, x-1);
    if (Maxsum < 0)
        cout << 0;
    else
        cout << Maxsum; 
    return 0;
}

总结

1.< 是否为递归>每次都进行二分,都是将总的分为2,再从左边最大值和右边最大值还有中间衍生的最大值这3者中取最大值。
2.< 结束条件>二分的结果必定是只剩一个
3.< 每次实现功能以及返回信息>算出3者大小,返回最大值