归并排序
2012-08-05 19:41 coodoing 阅读(413) 评论(0) 编辑 收藏 举报1、算法介绍
归并排序(Merging Sort)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的;然后再把有序子序列合并为整体有序序列。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
2、算法动画演示
3、算法步骤
1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。
2、设定两个指针,最初位置分别为两个已经排序序列的起始位置。
3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置。
4、重复步骤3直到某一指针达到序列尾。
5、将另一序列剩下的所有元素直接复制到合并序列尾。
4、算法代码
1: // 归并排序算法
2: public class MergingSort {
3:
4: public static void mergeSort(int[] arr) {
5: int[] temp = new int[arr.length];//临时数组
6: mSort(arr, temp, 0, arr.length - 1);
7: }
8:
9: private static void mSort(int[] arr, int[] temp, int low, int high) {
10: if (low >= high)
11: return;
12: else {
13: int middle = (low + high) / 2;
14: // 对左边数组进行递归
15: mSort(arr, temp, low, middle);
16: // 对右边数组进行递归
17: mSort(arr, temp, middle + 1, high);
18: // 合并
19: merge(arr, temp, low, middle, high);
20: }
21: }
22:
23: // 将有序数组ARR[low...middle]和ARR[middle+1...high]归并为有序的TEMP[low...high]
24: private static void merge(int[] arr, int[] temp, int low, int middle,
25: int high) {
26: // 左数组第一个元素的索引
27: int leftIndex = low;
28: // 右数组第一个元素索引
29: int rightIndex = middle + 1;
30: // tmpIndex 记录临时数组的索引
31: int tmpIndex = low;
32:
33: while (low <= middle && rightIndex <= high) {
34: // 从两个数组中取出最小的放入临时数组
35: if (arr[low] <= arr[rightIndex]) {
36: temp[tmpIndex++] = arr[low++];
37: } else {
38: temp[tmpIndex++] = arr[rightIndex++];
39: }
40: }
41: // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
42: while (rightIndex <= high) {
43: temp[tmpIndex++] = arr[rightIndex++];
44: }
45: while (low <= middle) {
46: temp[tmpIndex++] = arr[low++];
47: }
48:
49: // 将临时数组中的内容拷贝回原数组中: (原low-right范围的内容被复制回原数组)
50: while (leftIndex <= high) {
51: arr[leftIndex] = temp[leftIndex++];
52: }
53: }
54:
55: private static void print(int[] arr) {
56: for (int i = 0; i < arr.length; i++) {
57: System.out.print(arr[i] + "\t");
58: }
59: System.out.println();
60: }
61:
62: public static void main(String[] args) {
63: int arr[] = { 2, 568, 34, 46, 9, 23, 89, 43, 572, 684, 783, 543 };
64: System.out.println("归并排序前:");
65: print(arr);
66: mergeSort(arr);
67: System.out.println("归并排序后:");
68: print(arr);
69: }
70: }
5、算法时间复杂度
平均时间复杂度:O(nlgn)
最坏情况下时间复杂度为:O(nlgn)
归并排序算法稳定;数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n))。