数组排序简介-归并排序(Merge Sort)

基本思想

        采用经典的分治策略,先递归地将当前数组平均分成两半,然后将有序数组两两合并,最终合并成一个有序数组。  

算法步骤

假设数组的元素个数为 n 个,则归并排序的算法步骤如下:

  1. 分解过程:先递归地将当前数组平均分成两半,直到子数组长度为 1。
    1. 找到数组中心位置 mid,从中心位置将数组分成左右两个子数组 left_nums、right_nums。
    2. 对左右两个子数组 left_nums、right_nums 分别进行递归分解。
    3. 最终将数组分解为 n 个长度均为 1 的有序子数组。
  2. 归并过程:从长度为 1 的有序子数组开始,依次将有序数组两两合并,直到合并成一个长度为 n 的有序数组。
    1. 使用数组变量 nums 存放合并后的有序数组。
    2. 使用两个指针 left_i、right_i 分别指向两个有序子数组 left_nums、right_nums 的开始位置。
    3. 比较两个指针指向的元素,将两个有序子数组中较小元素依次存入到结果数组 nums 中,并将指针移动到下一位置。
    4. 重复步骤 3,直到某一指针到达子数组末尾。
    5. 将另一个子数组中的剩余元素存入到结果数组 nums 中。
    6. 返回合并后的有序数组 nums。

我们以 [0,5,7,3,1,6,8,4] 为例,演示一下归并排序算法的整个步骤。

适用场景

        大规模数据排序,要求稳定性的排序需求,外部排序,并行计算环境        

排序稳定性

        因为在两个有序子数组的归并过程中,如果两个有序数组中出现相等元素,merge(left_nums, right_nums): 算法能够使前一个数组中那个相等元素先被复制,从而确保这两个元素的相对顺序不发生改变。因此,归并排序算法是一种 稳定排序算法

代码实现(golang)

// 归并排序
func MergeSort(arr []int) []int {
	if len(arr) <= 1 {
		return arr
	}
	mid := len(arr) / 2
	left_arr := MergeSort(arr[:mid])
	right_arr := MergeSort(arr[mid:])
	arr1 := sort(left_arr, right_arr)
	return arr1
}

func sort(left []int, right []int) []int {
	var result []int
	// 将两个有序子数组中较小元素依次插入到结果数组中
	l, r := 0, 0
	for l < len(left) && r < len(right) {
		if left[l] < right[r] {
			result = append(result, left[l])
			l++
		} else {
			result = append(result, right[r])
			r++
		}
	}
	if l < len(left) {
		for l < len(left) {
			result = append(result, left[l])
			l++
		}
	}
	if r < len(right) {
		for r < len(right) {
			result = append(result, right[r])
			r++
		}
	}
	return result
}


func main() {
    arr := []int{4, 2, 2, 8, 3, 3, 1}
    sortedArr := MergeSort(arr)
    fmt.Println(sortedArr)

猜你喜欢

转载自blog.csdn.net/Runing_WoNiu/article/details/143403139