归并排序(自顶向下)
算法概述
归并排序的基本思想是分而治之。首先把待排序的序列拆分为两个子序列,这两个子序列又各自拆分为两个子序列,就这样不断的向下拆分,直到每个子序列只有一个元素。接着开始合并子序列形成一个较长的有序子序列,合并后的子序列又为下一次合并做准备,直到所有子序列都合入到一个整体,所有数据有序。
算法实现
package main
import (
"fmt"
)
func MergeSort(nums []int) {
if len(nums) <= 1 {
return
}
temp := make([]int, len(nums))
mergeSort(nums, temp, 0, len(nums)-1)
}
func mergeSort(array, temp []int, left, right int) {
if left >= right {
return
}
mid := left + (right-left)/2
mergeSort(array, temp, left, mid)
mergeSort(array, temp, mid+1, right)
if array[mid] > array[mid + 1] {
merge(array, temp, left, mid, right)
}
}
func merge(array, temp []int, left, mid, right int) {
i, j := left, mid+1
// 将当前子数组的内容复制到临时数组 temp 中
// 简化代码逻辑,避免覆盖未处理的元素
copy(temp[left:right+1], array[left:right+1])
// 合并两个有序子数组
for k := left; k <= right; k++ {
if i > mid {
// 左子数组已处理完,直接复制右子数组的元素
array[k] = temp[j]
j++
} else if j > right {
// 右子数组已处理完,直接复制左子数组的元素
array[k] = temp[i]
i++
} else if temp[i] <= temp[j] {
// 左子数组的当前元素小于等于右子数组的当前元素
array[k] = temp[i]
i++
} else {
// 右子数组的当前元素小于左子数组的当前元素
array[k] = temp[j]
j++
}
}
}
func main() {
arr := []int{3, 5, 1, 6, 2, 7, 4}
fmt.Println("Unsorted array:", arr)
MergeSort(arr)
fmt.Println("Sorted array:", arr)
}