分治算法的完美使用----归并排序

Posted xiaoyh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治算法的完美使用----归并排序相关的知识,希望对你有一定的参考价值。

归并排序(Merge Sort)算法完全依照了分治模式
  分解:将 n 个元素分成各含 n/2 个元素的子序列;
  解决:对两个子序列递归地排序;
  合并:合并两个已排序地子序列以得到排序结果;
和快速排序不同的是
  归并的划分比较随意,快排重点就是划分
  归并的重点就是合并,快排不需要合并

代码:

import java.util.Arrays;

public class MergeSort {

    public static void main(String[] args) {
        int arr[] = new int[10];
        for(int i=0;i<10;i++){
            arr[i] = (int) ((Math.random()+1)*10);
        }
        
        
        System.out.println("排序前:"+Arrays.toString(arr));
        mergeSort(arr, 0, arr.length-1);
        System.out.println("排序后:"+Arrays.toString(arr));

    }
    
    /**
     * 思路:将数组分为左右两个数组,递归调用归并进行排序
     *         分别排序完成后,使用辅助的合并函数将两个有序的子数组合并成一个整体有序的数组
     * 时间复杂度:均:O(nlgn),好:O(nlgn),坏:O(nlgn)
     * 空间复杂度:需要开辟辅助空间,该辅助空间可以重用,大小为N
     * 非原址排序
     * 稳定性:所有排序都是归并,在左的永远在左,在右的永远在右,稳定
     */
    
    static int[]helper;
    
    private static void mergeSort(int[] arr, int p, int r) {
        
        if (p<r) {
            int mid = p + ((r-p)>>1);
            mergeSort(arr, p, mid);  // 对左侧排序
            mergeSort(arr, mid+1, r);  // 对右侧排序
            merge(arr,p,mid,r);    // 合并
        }
        
    }

    private static void merge(int[] arr, int p, int mid, int r) {
        
        // 下面这行代码只能在这里使用,不能在主方法使用。
        helper = Arrays.copyOf(arr, arr.length);  //开辟的一个辅助空间  并拷贝数据
        
        int left = p;  // 左侧队伍的头部指针,指向待比较的元素
        int right = mid + 1;   // 右侧队伍的头部指针,指向待比较的元素
        int current = p;       // 原数组的指针,指向待填入数据的位置
        
        while(left<=mid&&right<=r){
            if (helper[left]<=helper[right]) {
                arr[current] = helper[left];
                current++;
                left++;
            }else {
                arr[current] = helper[right];
                current++;
                right++;
            }
        }
        
        // 如果辅助数组右侧的数据没有全部填入原数组  那么不用管 因为原数组数据存在的
        // 那么只需要考虑辅助数组左侧的数据没有全部填入原数组的情况
        if (left<=mid) {
            while(left<=mid){
                arr[current] = helper[left];
                current++;
                left++;
            }
        }
        
    }

}

结果:

  技术分享图片

 

以上是关于分治算法的完美使用----归并排序的主要内容,如果未能解决你的问题,请参考以下文章

算法浅谈——分治算法与归并快速排序(附代码和动图演示)

排序算法6 —— 归并排序

python代码实现归并排序(Merge Sort )

递归分治算法-归并排序算法

算法与数据结构:时间复杂度——以归并排序为例

分治算法-归并排序快速排序