排序算法之归并

归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾

 

  归并排序Merge sort            稳定时间复杂度O(n log n

  空间复杂度O(n)

publicclass MSort {

publicstaticvoid main(String []args){

        int []arr = {1,2,3,4,5,6,7,8,9,10,11};

        aasort(arr);//排序

        System.out.println(Arrays.toString(arr));

    }

    publicstaticvoid aasort(int []arr){//

        int []temp = newint[arr.length];//创建一个数组,用于接收排序的数组

        bbsort(arr,0,arr.length-1,temp);//调用bbsort

    }

    privatestaticvoid bbsort(int[] arr,int left,int right,int []temp){

        if(left<right){

            int mid = (left+right)/2;

            bbsort(arr,left,mid,temp);//左边归并排序,使得左子序列有序

            bbsort(arr,mid+1,right,temp);//右边归并排序,使得右子序列有序

            merge(arr,left,mid,right,temp);//将两个有序子数组合并操作

        }

    }

    privatestaticvoid 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++];}

            }

 

        while(i<=mid){temp[t++] = arr[i++];}

 

        while(j<=right){temp[t++] = arr[j++];}

 

        t = 0;

        while(left <= right){arr[left++] = temp[t++];//temp中的元素全部copy到原数组中

        }

    }

 

}

publicclass MSort {

    publicstaticvoid main(String []args){

        int []arr = {9,8,7,6,5,4,3,2,1};

        sort(arr);

        System.out.println(Arrays.toString(arr));

    }

    publicstaticvoid sort(int []arr){

        int []temp = newint[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间

        sort(arr,0,arr.length-1,temp);

    }

    privatestaticvoid sort(int[] arr,int left,int right,int []temp){

        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);//将两个有序子数组合并操作

        }

    }

    privatestaticvoid 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++];

            }

        }

        while(i<=mid){//将左边剩余元素填充进temp

            temp[t++] = arr[i++];

        }

        while(j<=right){//将右序列剩余元素填充进temp

            temp[t++] = arr[j++];

        }

        t = 0;

        //temp中的元素全部拷贝到原数组中

        while(left <= right){

            arr[left++] = temp[t++];

        }

    }

}

 

 

posted @ 2018-04-17 16:56  haiming_wen  阅读(166)  评论(0)    收藏  举报