最近看了不少递归的例子,突然有了点想法
其实递归,就是不断地调用自身。如果不好理解,就理解成是不断地调用同一个方法,只不过这个方法是自己。
递归的具体过程涉及到栈内存等,这里就不写了,写写我的一些看法吧
递归主要一个就是对结果的处理,一般来说,递归到最深一层时开始返回,然后返回的过程中呢,会带回一个结果
比如并排站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); }
但是斐波那契用递归有硬伤