go语言实现排序算法3 | 青训营笔记

131 阅读3分钟

归并排序(Merge Sort)是一种高效的排序算法,它采用分治策略。算法的基本思想是将待排序的数组递归地分成两半,然后对每个子数组进行排序,最后将两个有序的子数组合并为一个有序的数组。归并排序的时间复杂度是 O(nlogn),其中 n 是待排序数组的长度。

堆排序(Heap Sort)是一种基于二叉堆数据结构的排序算法。堆是一个完全二叉树,具有以下性质:父节点的值大于等于(或小于等于)其子节点的值。堆排序的基本思想是首先将待排序的数组构建成一个最大堆(或最小堆),然后逐步将堆顶的元素与末尾元素交换,并对剩余的元素重新调整堆,直到整个数组有序。堆排序的时间复杂度也是 O(nlogn)。

归并排序和堆排序都属于比较型排序算法,它们的稳定性较好。稳定性是指相等元素的相对顺序在排序后是否保持不变。归并排序是稳定的,而堆排序在原地排序时(即在待排序数组上直接进行操作)是不稳定的,但可以通过一些额外的操作来实现稳定性。

在实际应用中,归并排序常用于外部排序,例如对大规模数据的排序,而堆排序常用于优先队列等数据结构的实现。它们在处理大规模数据时具有较好的性能。归并排序和堆排序是两种常用的排序算法,它们在不同的应用场景下都具有高效的排序能力。

归并排序(Merge Sort): 归并排序是一种分治策略的排序算法,它将待排序的数据分割成小问题,然后逐步解决这些问题,最后将解决的结果合并起来。具体实现如下:

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 := make([]int, 0)

	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{9, 5, 1, 3, 7, 4, 8, 2, 6}
	sortedArr := mergeSort(arr)
	fmt.Println(sortedArr)
}

在上述代码中,我们定义了mergeSort函数来实现归并排序,该函数通过递归将待排序数组分割为更小的子数组,然后调用merge函数合并两个有序子数组。merge函数将左右两个有序子数组合并为一个有序数组。

堆排序(Heap Sort): 堆排序是一种基于二叉堆数据结构的排序算法,它通过将待排序的数据构建成一个堆,然后逐步将最大(或最小)元素从堆中移除,从而得到有序序列。具体实现如下:

package main

import (
	"fmt"
)

// 堆排序
func heapSort(arr []int) {
	n := len(arr)

	// 构建最大堆
	for i := n/2 - 1; i >= 0; i-- {
		heapify(arr, n, i)
	}

	// 逐步将最大元素移动到数组末尾
	for i := n - 1; i > 0; i-- {
		// 将当前最大元素与末尾元素交换
		arr[0], arr[i] = arr[i], arr[0]
		// 重新调整堆
		heapify(arr, i, 0)
	}
}

// 调整堆
func heapify(arr []int, n, i int) {
	largest := i
	left := 2*i + 1
	right := 2*i + 2

	// 找到左子节点和右子节点中的最大值
	if left < n && arr[left] > arr[largest] {
		largest = left
	}
	if right < n && arr[right] > arr[largest] {
		largest = right
	}

	// 如果最大值不是当前节点,则交换节点,并继续调整堆
	if largest != i {
		arr[i], arr[largest] = arr[largest], arr[i]
		heapify(arr, n, largest)
	}
}

func main() {
	arr := []int{9, 5, 1, 3, 7, 4, 8, 2, 6}
	heapSort(arr)
	fmt.Println(arr)
}

在上述代码中,我们定义了heapSort函数来实现堆排序,该函数首先通过调用heapify函数构建最大堆,然后逐步将堆顶的最大元素与末尾元素交换,并调整堆,直到整个数组有序。

以上就是使用Go语言实现归并排序和堆排序的代码示例。无论是归并排序还是堆排序,在实际应用中都具有较高的效率和稳定性。你可以根据自己的需求选择其中之一来进行排序操作。希望对你有所帮助!