• 递归小结


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

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

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

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

    比如并排站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

  • 相关阅读:
    (深入理解计算机系统)内存对齐
    (深入理解计算机系统)AT&T汇编指令
    (深入理解计算机系统)编译,链接和装载
    (C)struct结构体指针
    (linux)BSP板级支持包开发理解
    TortoiseSVN使用笔记
    (linux)idr(integer ID management)机制
    (linux)struct inode 和 struct file
    cygwin使用笔记
    Zookeeper学习总结
  • 原文地址:https://www.cnblogs.com/tech-bird/p/3890992.html
Copyright © 2020-2023  润新知