再说递归
两种情况:
1:
package com.test.Sort; public class Test { public static void main(String[] args) { int facs = facs(4); System.out.println(facs); } /* * * 第一次:n=4 4*函数(4-1) ->4*facs(3) * 第二次:n=3 3*函数(3-1) ->4*facs(2) * 第三次:n=2 3*函数(2-1) ->4*facs(1) * 第四次:n=1 返回1 然后退出 * 每次递归相当于开辟一个新栈,倒叙,栈是先进后出: * 最后如下:1*2*3*4=24 * * */ public static int facs(int n){ if(n==1){ return 1; }else{ return n*facs(n-1); } } }
2:
package com.test.Sort; public class Test { public static void main(String[] args) { int facs = facs(4); System.out.println(facs); } public static int facs(int n){ //第一次 n=4 4*facs(4-1) //第二次 n=3 4*facs(3-1); //第三次 n=2 不符合条件 return退出函数 //最后就是3*4=12 if(n>2){ return n*facs(n-1); } return 1; } }
学习归并排序深度理解递归:
package com.test.Sort; import java.util.Arrays; public class Merge_Sort { public static void main(String[] args) { //使用最少测试项 int[] arr = {2,1}; sort(arr); System.out.println(Arrays.toString(arr)); } public static void sort(int[] arr){ //开辟临时数组 int[] temp = new int[arr.length]; sort(arr,0,arr.length-1,temp); } private static void sort(int[] arr,int left,int right,int[] temp){ //left right都是索引 if(left<right){ int mid = (left+right)/2; sort(arr,left,mid,temp); //左序列排序 sort(arr,mid+1,right,temp); //右序列排序 //左右两边序列合并 Merge(arr,left,mid,right,temp); } } private static void Merge(int[] arr,int left,int mid,int right,int[] temp){ int i = left; //左序列指针 int j = mid+1; //右序列指针 int t = 0; //临时数组指针 while(i<=mid && j<=right){ if(arr[i]<=arr[j]){ temp[t++] = arr[i++]; }else{ temp[t++] = arr[j++]; } } //将左边剩余元素填充进temp中 while(i<=mid){ temp[t++] =arr[i++]; } //将右序列剩余元素填充进temp中 while(j<=right){ temp[t++] = arr[j++]; } t = 0; //将temp中的元素全部拷贝到原数组中 while(left <=right){ arr[left++] = temp[t++]; } } }
debug走了好几圈,递归真的很费劲,手工debug分析下:
[2,1] arr=[2,1] //原数组 temp=[0,0] //临时数组->存储数据 sort(arr,0,1,temp) 第一次 left=0 right=1 满足条件->进入条件语句: mid=(0/1)/2=0 -mid=0 调用sort函数递归:sort(arr,0,0,temp); 此时left=0 right=0 temp不变 发现不满足条件,那么此时right=1 调用函数,不满足条件,退出这个递归: 进入下一个递归: 此left=1 right=1 mid=0 满足条件->进入条件语句: 不满足退出 至此 left=0 right=1 mid=0 进入下一个函数调用 Merge(arr,0,0,1,temp) i=0 j=1 0<=0 &&1<=1 arr[0]=2 arr[1]=1 不符合条件走:temp[t++] = arr[j++]; 小的放前面去 变成了 temp[0]=1 t++ t=1 j=2 继续循环: 0<=0 && 2<=1 不符合条件: 下一个循环: 0<=0 符合条件: temp[t++]=arr[i++]; temp[1]=arr[0] temp[1]=2 i++; i=1 t=3 j=2 此时此刻temp=[1,2] 最后一个循环: 2<=1 不符合条件: 重置t 最后: i=1 t=0 j=2 left=0 right=1 下一个循环 0<1 把temp数组中的数据全部拷贝给arr arr[left++]=temp[t++]; 之后left=1 t=1 right=1 arr[0]=temp[0]; 第二次循环: left<=right: left=1 t=1 right=1 arr[1]=temp[1] 然后 left=2 t=2 right=1 第三次判断: left<=right 2<=1 不符合条件,不进循环 最后arr就是[1,2]