归并排序

来源:互联网 发布:淘宝买家信誉快速 编辑:程序博客网 时间:2024/06/05 22:39

归并排序

一、介绍

1、概念

归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

2、基本思想

这里写图片描述
只有一个元素的表总是有序的,所以将表arr[1…n],看做n个长度len=1的有序子表,对相邻的两个有序子表两两合并到temp[1…n]中,使之生成表长len=2的有序表,在进行两两合并,直到最后生成表长为n的有序表,整个过程需要log2n(log以2为底n的对数)趟。

归并过程中有个需要解决的问题就是分组问题,因为表长不总是2的整数幂,这样最后一组就不能保证是表长为len的有序表,也不能保证每趟排序中都有偶数个有序子表。

二、算法实现

/** * 归并排序 需要考虑三种情况 1、正好可以分成整个的偶数组 2、可以分成偶数组,但是最后一组中元素数量不足 3、只能分成奇数组 *  * @param arr */public static void mergeSort(int[] arr) {    for (int i = 1; i < arr.length; i*=2) {        mergePass(arr, i);    }}/** * 从arr中归并到temp中 *  * @param arr * @param len *            本趟归并中有序表的长度 */public static void mergePass(int[] arr, int len) {    System.out.println("len:"+len);    int i;    int[] temp = new int[arr.length];    for (i = 0; i + 2 * len-1 < arr.length; i = i + 2 * len) {        merge(arr, temp, i, i + len - 1, i + 2 * len - 1);// 对两个长度为len的表进行合并    }    if (i + len - 1 < arr.length - 1) {// 剩余长度不够len,当剩余的总个数大于len        merge(arr, temp, i, i + len - 1, arr.length - 1);    } else if (i <= arr.length - 1) {// 剩余长度不足len        while (i <= arr.length - 1) {            temp[i] = arr[i++];        }    }    System.arraycopy(temp, 0, arr, 0, arr.length);    print(arr);}//对两个有序子表进行归并public static void merge(int[] arr, int[] temp, int low, int mid, int height) {    int i = low;    int j = mid + 1;    int k = low;    while (i <= mid && j <= height) {        if (arr[i] > arr[j]) {            temp[k++] = arr[j++];        } else {            temp[k++] = arr[i++];        }    }    while (i <= mid) {        temp[k++] = arr[i++];    }    while (j <= height) {        temp[k++] = arr[j++];    }}

三、运行结果

这里写图片描述

四、性能分析

稳定性:稳定
时间复杂度:O(nlogn) (n倍的log以2为底n的对数)

原创粉丝点击