基本思想
归并排序利用分治法思想,先将一个序列分成一个个子序列,然后对子序列进行排序,再把有序子序列合并为整体有序序列。
两路归并排序算法思路:
①把 n 个记录看成 n 个长度为1的有序子表;
②进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表;
③重复第②步直到所有记录归并成一个长度为 n 的有序表为止。
Java代码
import java.util.Arrays; public class MergeSort { public static int[] sort(int[] a, int left, int right) { if (left >= right) { return a; } int mid = (left + right) / 2; sort(a, left, mid); sort(a, mid + 1, right); return merge(a, left, mid, right); } private static int[] merge(int[] a, int left, int mid, int right) { int[] tmp = new int[right + 1]; int center = mid + 1; int index = left; // 记录临时数组的下标 int temp = left; // 从两个数组中选择最小的放入临时数组 while (left <= mid && center <= right) { tmp[index++] = (a[left] <= a[center]) ? a[left++] : a[center++]; } // 剩余部分放入临时数组 while (center <= right) { tmp[index++] = a[center++]; } while (left <= mid) { tmp[index++] = a[left++]; } // 将临时数组copy回原数组 for (int i = temp; i <= right; i++) { a[i] = tmp[i]; } return a; } public static void main(String[] args) { int[] arr = new int[] { 14, 12, 15, 13, 11, 16 }; arr = sort(arr, 0, arr.length - 1); System.out.println(Arrays.toString(arr)); } }
算法分析
(1)稳定性
归并排序是一种稳定的排序。
(2)存储结构要求
可用顺序存储结构。也易于在链表上实现。
(3)时间复杂度
对长度为n的文件,需进行二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
(4)空间复杂度
需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
注意:若用单链表做存储结构,很容易给出就地的归并排序。