归并排序的原理
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子 序列段间有序。
归并排序的实现
public class Sort {
public static void mergeSort(int[] array) {
mergeSortHelper(array, 0, array.length);
}
private static void mergeSortHelper(int[] array, int left, int right) {
if (left >= right || right - left == 1) {
return;
}
int mid = (left + right) / 2;
mergeSortHelper(array, left, mid);
mergeSortHelper(array, mid, right);
merge(array, left, mid, right);
}
private static void merge(int[] array, int left, int mid, int right) {
int length = right - left;
int[] temp = new int[length];
int tempIndex = 0;
int i = left;
int j = mid;
while (i < mid && j < right) {
//加入 = 使得数据稳定
if (array[i] <= array[j]) {
temp[tempIndex++] = array[i++];
}else {
temp[tempIndex++] = array[j++];
}
}
while (i < mid) {
temp[tempIndex++] = array[i++];
}
while (j < right) {
temp[tempIndex++] = array[j++];
}
for (int k = 0; k < length; k++) {
array[left + k] = temp[k];
}
}
public static void main(String[] args) {
int[] arr = {9, 5, 2, 7, 3, 6, 1, 8};
mergeSort(arr);
System.out.println(Arrays.toString(arr));
}
}
性能分析
时间复杂度 | 空间复杂度 |
---|---|
O(n * log(n)) | O(n) |
数据不敏感 | 数据不敏感 |
非递归版本
public static void mergrSortByLoop(int[] array) {
for (int i = 1; i < array.length; i = i * 2) {
for (int j = 0; j < array.length; j = j+ 2 * i) {
int low = j;
int mid = j + i;
if (mid >= array.length) {
continue;
}
int high = mid + 1;
if (high > array.length) {
high = array.length;
}
merge(array, low, mid, high);
}
}
}
海量数据的排序问题
外部排序:排序过程需要在磁盘等外部存储进行的排序
前提:内存只有 1G,需要排序的数据有 100G 因为内存中因为无法把所有数据全部放下,所以需要外部排序,而归并排序是最常用的外部排序
- 先把文件切分成 200 份,每个 512 M
- 分别对 512 M 排序,因为内存已经可以放的下,所以任意排序方式都可以 3. 进行 200 路归并,同时对 200 份有序文件做归并过程,最终结果就有序了