再说递归

    两种情况:

  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]

 

 

    

posted @ 2021-03-16 10:30  飘渺红尘✨  阅读(60)  评论(0编辑  收藏  举报
Title