排序算法是计算机科学中的重要部分,也是日常编程中经常遇到的问题。常用的排序算法包括插入排序、快速排序、堆排序等。这些算法各有优缺点,需要结合具体场景选择不同的算法进行优化。
本篇笔记主要介绍Go语言实现的插入排序、快速排序和堆排序。
- 插入排序
(1)原理及特点
插入排序是一种简单直观的排序算法,其基本思路是:将待排序的数据分成已排序部分和未排序部分。每次从未排序部分中选取一个元素,插入到已排序部分的正确位置上。这个过程一直进行到未排序部分为空,排序完成。
插入排序的时间复杂度为 ,空间复杂度为 ,最好情况下可以达到 ,具有稳定性。
(2)代码实现
下面是Go语言实现的插入排序代码:
func insertionSort(arr []int) {
for i := 1; i < len(arr); i++ {
for j := i; j > 0 && arr[j-1] > arr[j]; j-- {
arr[j-1], arr[j] = arr[j], arr[j-1]
}
}
}
(3)测试示例
下面是一个基本测试示例:
func TestInsertionSort(t *testing.T) {
arr := []int{2, 3, 5, 1, 4}
insertionSort(arr)
want := []int{1, 2, 3, 4, 5}
if !reflect.DeepEqual(arr, want) {
t.Errorf("want %v but got %v", want, arr)
}
}
- 快速排序
(1)原理及特点
快速排序是一种常见的排序算法,其基本思路是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小。然后再分别对前后两部分记录继续进行快速排序,直到整个序列有序。
快速排序的时间复杂度为 ,空间复杂度为 ,不稳定。
(2)代码实现
下面是Go语言实现的快速排序代码:
func quickSort(arr []int, left, right int) {
if left >= right {
return
}
p := partition(arr, left, right)
quickSort(arr, left, p-1)
quickSort(arr, p+1, right)
}
func partition(arr []int, left, right int) int {
pivot := arr[left]
for left < right {
for left < right && arr[right] >= pivot {
right--
}
arr[left] = arr[right]
for left < right && arr[left] <= pivot {
left++
}
arr[right] = arr[left]
}
arr[left] = pivot
return left
}
(3)测试示例
下面是一个基本测试示例:
func TestQuickSort(t *testing.T) {
arr := []int{2, 3, 5, 1, 4}
quickSort(arr, 0, len(arr)-1)
want := []int{1, 2, 3, 4, 5}
if !reflect.DeepEqual(arr, want) {
t.Errorf("want %v but got %v", want, arr)
}
}
- 堆排序
(1)原理及特点
堆排序利用堆的性质进行排序,其基本思路是:将待排序的序列构造成一个大根堆(或小根堆),然后将堆顶元素与末尾元素进行交换,此时末尾元素就为最大(或最小)值,再将堆调整为大根堆(或小根堆),重复以上步骤,直到整个序列有序。
堆排序的时间复杂度为 ,空间复杂度为 ,不稳定。
(2)代码实现
下面是Go语言实现的堆排序代码:
func heapSort(arr []int) {
n := len(arr)
// 构造大根堆
for i := n/2 - 1; i >= 0; i-- {
heapify(arr, i, n)
}
// 进行堆排序
for i := n - 1; i > 0; i-- {
arr[0], arr[i] = arr[i], arr[0]
heapify(arr, 0, i)
}
}
func heapify(arr []int, i, n int) {
for {
maxPos := i
if left := 2*i + 1; left < n && arr[left] > arr[maxPos] {
maxPos = left
}
if right := 2*i + 2; right < n && arr[right] > arr[maxPos] {
maxPos = right
}
if maxPos == i {
break
}
arr[i], arr[maxPos] = arr[maxPos], arr[i]
i = maxPos
}
}
(3)测试示例
下面是一个基本测试示例:
func TestHeapSort(t *testing.T) {
arr := []int{2, 3, 5, 1, 4}
heapSort(arr)
want := []int{1, 2, 3, 4, 5}
if !reflect.DeepEqual(arr, want) {
t.Errorf("want %v but got %v", want, arr)
}
}
在编写排序算法的过程中,我们需要注意编写高效、简洁、易读的代码,并保证代码的正确性。因此,在编写代码之前,我们可以充分理解算法的原理和特点,并通过测试来保证代码的正确性。