天天看点

归并排序(详细注释)

归并排序

归并采用了分而治之的思想,也就是分治法。

例如数据9,8,7,6,5,4,3,2,1

一串数字,以二分法的方式将数据不断的递归截取成两部分,直到数据只有2位

从此开始,将每次递归返回后的左递归数据段和右递归的数据段想比较排序,得出从小到大的顺序

public static void main(String[] args) {
        System.out.println("归并排序--");
        
    //待排序的数组数据
    	int[] arr = new int[80000000];
        for(int i=0;i<arr.length;i++){
            arr[arr.length-i-1] = i;
        }

        Date date =new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss SSS");
        System.out.println(simpleDateFormat.format(date.getTime()));

		//中转数组,用于暂时存放数据
        int[] temp = new int[arr.length];
        mergeSort(arr,0,arr.length-1,temp);


        Date date1 =new Date();
        System.out.println(simpleDateFormat.format(date1.getTime()));
    	//以上代码均是为了观测算法运行效率
    
    }

    public static void mergeSort(int[] arr,int left,int right,int[] temp){
        if(left<right){
            int mid = (right+left)/2;
            //左递归
            mergeSort(arr,left,mid,temp);
            //右递归
            mergeSort(arr,mid+1,right,temp);
            //对左递归的数据和有递归的数据进行一次排序,每次比较的是从左到右的数据小的先放入中转数组
            merge(arr,left,mid,right,temp);
        }
    }

    public static void merge(int[] arr,int left,int mid,int right,int[] temp){
        int i = left;
        int j = mid+1;
        int t=0;
		//左递归数据的最左开始(left)与右递归的最左开始(mid+1),相比较,发现较小的数就优先将较小的数据放入temp中,将放入的数据的下标+1,找到后面一个数,再次比较,直到其中一个递归的数据全部存入temp中,另一个递归的数据,接下来处理
        while (i<=mid && j<=right){
            if(arr[i]<=arr[j]){
                temp[t] = arr[i];
                i++;
                t++;
            }else{
                temp[t] = arr[j];
                j++;
                t++;
            }
        }
        
        //i<=mid判断左递归的数据是否还有剩余,右则全部依次存入temp中,这些数据就是之前遗留数据
        while (i<=mid){
            temp[t] = arr[i];
            i++;
            t++;
        }
        
        //j<=right判断右递归的数据是否还有剩余,右则全部依次存入temp中,这些数据就是之前遗留数据
        while (j<=right){
            temp[t] = arr[j];
            j++;
            t++;
        }
        //t是temp的下标,先清零,找到开头
        t=0;
        //
        int templeft = left;
        //表示将temp中的数据放入arr总是从left的下标开始,因为各个递归中left总是链接者靠左递归的right+1,得以数据存储连续
        while (templeft<=right){
            arr[templeft] = temp[t];
            t++;
            templeft++;
        }
    }
           

继续阅读