递归小结

最近看了不少递归的例子,突然有了点想法

其实递归,就是不断地调用自身。如果不好理解,就理解成是不断地调用同一个方法,只不过这个方法是自己。

递归的具体过程涉及到栈内存等,这里就不写了,写写我的一些看法吧

递归主要一个就是对结果的处理,一般来说,递归到最深一层时开始返回,然后返回的过程中呢,会带回一个结果

比如并排站10个人,第一个人想向第10个人要一个苹果,那么他就向第2个人说,给我一个苹果,然后第2个向第3个,第3个向第4个。。。

我感觉分为四类

1.一类是直接使用最深层的结果,也就是不断往上传递,一直传递到第一层,中间不做任何处理。

也就是话传到第十个人的时候,返回一个苹果,然后这个苹果完整的由第9,第8.。。。一直传到第1个

2.一类是在从最深层向上传递结果的过程中,在经过的 每一层中都要对结果进行一下处理,加上本层的一些修饰

就是说把结果返回给上层,而不是返回给顶层

比如苹果在从第9个人向第1个人传递的过程中,每个人签了一个字,这样第一个人就得到了一个具有9个人签字的苹果

3.还有一类是不用返回结果,只需要每一个人做一个动作即可。

4.还有一类就是多个递归同时进行

举三个例子说明一下这些情况吧:

前两种情况都需要定义一个变量,

然后根据条件判断出最后一层,返回最后一层的返回值,

然后再考虑其它层

第一个

旋转数组的最小数字

//4 5 6 7 1 2 3
    private static int GetMinValue(int[] num,int start,int end) {
        
        int min=0;        
        if(start == end)
        {
            return num[start];
        }
        
        int mid = (start+end)/2;        
        if(num[start] < num[mid])
        {
            min = GetMinValue(num, mid, end); 
        }else if(num[start] > num[mid])
        {
            min = GetMinValue(num, start, mid);
        }else if(num[start] == num[mid])        
        {
            min = num[start]>num[end]?num[end]:num[start];
        }
        
        return min;
    }


第二个:

合并两个排序的链表(或者快速排序)

ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
    if(pHead1 == NULL)
        return pHead2;
    else if(pHead2 == NULL)
        return pHead1;

    ListNode* pMergedHead = NULL;

    if(pHead1->m_nValue < pHead2->m_nValue)
    {
        pMergedHead = pHead1;
        pMergedHead->m_pNext = Merge(pHead1->m_pNext, pHead2);
    }
    else
    {
        pMergedHead = pHead2;
        pMergedHead->m_pNext = Merge(pHead1, pHead2->m_pNext);
    }

    return pMergedHead;
}


这个例子可以看出,每一层的结果向上传递都是经过处理的

private static void qKSort(int[] vals,int low,int high) {
        if(vals==null || vals.length == 0)
            return ;
        
        int pos;
        if(low <high)
        {
            pos = qKPass(vals,low,high);
            qKSort(vals, low, pos-1);
            qKSort(vals, pos+1, high);
        }
        
    }

    private static int qKPass(int[] vals, int left, int right) {
        int pivotKey = vals[left];
        
        while(left<right)
        {
            while(left<right && vals[right]>= pivotKey)
                right--;
            
            vals[left] = vals[right];
            
            while(left<right && vals[left] <= pivotKey)
                left++;
            
            vals[right] = vals[left];
        }
        
        vals[left] = pivotKey;
        
        return left;
    }
快速排序

第3种

这种最经典的例子就是汉诺塔了

void hanoi(int n,char one,char two,char three){
/*将n个盘从one座借助two座,移到three座*/
  if(n==1) move(one,1,three);
  else{
    hanoi(n-1,one,three,two);
    move(one,n,three);
    hanoi(n-1,two,one,three);
  }
}

第4种情况最经典的例子就是斐波那契数列了

int fib(int n)
{
    if(n==1 || n==2)
        return 1;
    return fib(n-1)+fib(n-2);
}


但是斐波那契用递归有硬伤

http://www.cnblogs.com/tech-bird/p/3857370.html

原文地址:https://www.cnblogs.com/tech-bird/p/3890992.html