归并排序适合处理大规模数据排序,尤其是当需要稳定排序时非常有用

归并排序原理

  1. 分治Divide,将数组从中间分成两半
  2. 解决conquer,递归地对左右两半分别进行归并排序
  3. 合并combine,将两个已排序的子数组合并成一个有序数组
  • 时间复杂度:O(n logn)
  • 空间复杂度:O(n),需要额外数组用于合并
  • 稳定排序,相同元素的相对顺序保持不变

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package main

import "fmt"

func mergeSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}

mid := len(arr) / 2
left := mergeSort(arr[:mid])
right := mergeSort(arr[mid:])

return merge(left, right)
}

func merge(left, right []int) []int {
result := []int{}
i, j := 0, 0
for i < len(left) && j < len(right) {
if left[i] <= right[j] {
result = append(result, left[i])
i++
} else {
result = append(result, right[j])
j++
}
}
result = append(result, left[i:]...)
result = append(result, right[j:]...)
return result
}

func main() {
arr := []int{5, 2, 4, 6, 1, 3}
sorted := mergeSort(arr)
fmt.Println(sorted) // [1 2 3 4 5 6]
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.util.Arrays;

public class MergeSort {
public static void mergeSort(int[] arr) {
if (arr.length <= 1) return;
mergeSortHelper(arr, 0, arr.length - 1);
}

private static void mergeSortHelper(int[] arr, int left, int right) {
if (left >= right) return;
int mid = left + (right - left) / 2;
mergeSortHelper(arr, left, mid);
mergeSortHelper(arr, mid + 1, right);
merge(arr, left, mid, right);
}

private static void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = left, j = mid + 1, k = 0;

while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) temp[k++] = arr[i++];
else temp[k++] = arr[j++];
}

while (i <= mid) temp[k++] = arr[i++];
while (j <= right) temp[k++] = arr[j++];

for (int p = 0; p < temp.length; p++) arr[left + p] = temp[p];
}

public static void main(String[] args) {
int[] arr = {5, 2, 4, 6, 1, 3};
mergeSort(arr);
System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5, 6]
}
}