算法 归并排序

来源:互联网 发布:河海大学单片机实验 编辑:程序博客网 时间:2024/06/14 13:50

归并排序,顾名思义,就是“递归”和“合并”。

“归”的操作发生在对同一个数组的分组上。

“并”的操作体现了归并排序算法的思想。

一、归并排序的大体思想是(升序):

(1)有两个数组 a 和 b,它们都为升序排列的数组,分别为他们设置一个指针,pa 和 pb,都指向第一个元素。

(2)建立一个新合成的数组 c,用于存放排序后的结果,同样为它设置一个指针 pc,也指向第一个元素。 

(3)比较 pa 和 pb 指向的元素的大小,将指针指向元素较小的赋给数组 c 中 pc 指向的元素,将该指针和 pc 都+1。

(4)若 pa 和 pb 中有一个指针指到了数组的末端,则把另一个数组中的剩余元素直接复制到数组 c 的最后。

二、对于一个乱序的数组,应该怎么进行排序?

举个例子,对于9个元素组成的数组{3,4,6,7,2,8,9,12,0},我们可以将数组分成9组,也就是每一个元素单独成一组,一个元素一定是有序的。然后让它和相邻的组进行归并排序,这样新生成的组也是有序的。然后继续用新生成的组和其相邻的组进行归并排序。最终,合成一个大的有序数组。

具体的java代码如下:

public class MergeSort {    public static void mergeSort(int[] array, int start, int end) {        if (start < end) {        // 对半分        int mid = (start + end) / 2;        // 对中间位置以左进行归并排序            mergeSort(array, start, mid);             // 对中间位置以右进行归并排序            mergeSort(array, mid + 1, end);            // 对 array[start]到array[mid] 与 array[mid+1]到array[end] 进行归并排序            sort(array, start, end, mid);        }    }      public static void sort(int[] array, int start, int end, int mid) {        int[] temp = new int[end - start + 1];        int i = start;        int j = mid + 1;        int k = 0;        while (i <= mid && j <= end) {            if (array[i] <= array[j]) {                temp[k++] = array[i++];            } else {                temp[k++] = array[j++];            }        }        // 左边剩下的都挪过来        while (i <= mid) {            temp[k++] = array[i++];        }        // 右边剩下的都挪过来        while (j <= end) {            temp[k++] = array[j++];        }        // 把 temp 数组重新放回到 array 数组中        while (k > 0) {            array[--j] = temp[--k];        }    }    public static void main(String[] args) {        int[] array = { 3, 4, 6, 7, 2, 8, 9, 12, 0 };        mergeSort(array, 0, array.length - 1);        for (int i : array) {            System.out.print(i + " ");        }    }}

如增加一些打印语句,可以看到每一步的归并过程:

原始数组为:3 4 6 7 2 8 9 12 0 

第1次归并排序结果:3 4 6 7 2 8 9 12 0 

第2次归并排序结果:3 4 6 7 2 8 9 12 0 

第3次归并排序结果:3 4 6 2 7 8 9 12 0 

第4次归并排序结果:2 3 4 6 7 8 9 12 0 

第5次归并排序结果:2 3 4 6 7 8 9 12 0 

第6次归并排序结果:2 3 4 6 7 8 9 0 12 

第7次归并排序结果:2 3 4 6 7 0 8 9 12 

第8次归并排序结果:0 2 3 4 6 7 8 9 12 

最终结果为:0 2 3 4 6 7 8 9 12 

三、归并排序的时间复杂度

画出归并排序的递归树,可以看出树的高度为 logN,每一层比较的次数是N,所以平均时间复杂度为NlogN

0 0