You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.5 KiB

# 归并排序
* **介绍**
* `归并特性`
* 一个列表两段有序,通过归并实现合并成一段有序列表。
* 复杂度O(n log(n))
* 思路:先分解在合并
* 过程:
* 分解:将列表越分越小,直至分成一个元素;
* 终止条件:一个元素是有序的;
* 合并:将两个有序列表归并,列表越来越大。
* 关键字:
* 分解
* 归并
* 存在问题
* 需要额外的内存开销
* 快速排序 `>` 归并排序 `>` 堆排序
* **原理**
* 通过对若干个有序结点序列的归并来实现排序。
* 所谓归并是指将若干个已排好序的部分合并成一个有序的部分。
* **代码**
```go
/**
MergeSort 实现归并排序(前提列表有序)
包含:分解 + 合并
*/
func MergeSort(li []int, low, high int) {
if low < high {
mid := (low + high) / 2
MergeSort(li, low, mid)
MergeSort(li, mid + 1, high)
Merge(li, low, mid, high)
}
}
/**
Merge 归并
*/
func Merge(li []int, low, mid, high int) {
i, j, lt, t := low, mid + 1, make([]int, len(li)), 0
for i <= mid && j <= high { // 将结果拼接到新的数组
if li[i] < li[j] {
lt[t], i, t = li[i], i + 1, t + 1
} else {
lt[t], j, t = li[j], j + 1, t + 1
}
}
for i <= mid {
lt[t], i, t = li[i], i + 1, t + 1
}
for j <= high {
lt[t], j, t = li[j], j + 1, t + 1
}
for i, j := low, 0 ; i <= high; i, j = i + 1, j + 1 { // 因为存在递归,将数值填回数组
li[i] = lt[j]
}
}
```
* **过程**
![并归排序](.\img\归并排序.gif)