这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。
经典排序算法
插入排序
思想:把 n 个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有 n-1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。
缺点:平均和最坏情况的时间复杂度高达O(n^2)
优点:最好情况时间复杂度为O(n)
代码如下
package main
import (
"fmt"
)
func insertionSort(num []int) {
for i := 1; i < len(num); i++ {
for j := i; j > 0; j-- {
if (num[j] < num[j-1]) {
num[j], num[j - 1] = num[j - 1], num[j]
} else if (num[j] > num[j - 1]) {
break
}
}
}
}
func main() {
a := [...] int {1,84,25,48,74,2,94,51,58,51,65,47}
insertionSort(a[:])
fmt.Println(a)
}
快速排序
快速排序是一种划分交换排序,采用了分治的策略(通常称为分治法),基本思想是:
- 数据集中,选取一个元素作为'基准'(pivot)。
- 所有小于'基准'的元素,都移到'基准'的左边;所有大于'基准'的元素,都移到'基准'的右边。
- 对'基准'左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
代码如下
package main
import (
"fmt"
)
func QuickSort(arr []int) {
size := len(arr)
quickSortUtil(arr, 0, size-1)
}
func quickSortUtil(arr []int, lower int, upper int) {
if upper <= lower {
return
}
pivot := arr[lower]
start := lower
stop := upper
for lower < upper {
for arr[lower] <= pivot && lower < upper {
lower++
}
for arr[upper] > pivot && lower <= upper {
upper--
}
if lower < upper {
swap(arr, upper, lower)
}
}
swap(arr, upper, start)
quickSortUtil(arr, start, upper-1)
quickSortUtil(arr, upper+1, stop)
}
func swap(arr []int, first int, second int) {
arr[first], arr[second] = arr[second], arr[first]
}
func main() {
data := []int{9, 2, 5, 1, 7, 3, 6, 4, 8}
QuickSort(data)
fmt.Println(data)
}
堆排
利用堆的性质形成的排序方法
- 构造一个大根堆
- 将根节点(最大元素)交换到最后一个位置,调整整个堆,如此反复
package main
import "fmt"
func HeapSort(cha1n chan<-[]int, nums []int) {
Hepify(nums, len(nums))
for i := len(nums) - 1; i >= 0; i-- {
nums[i],nums[0] = nums[0],nums[i]
Hepify(nums, i)
}
cha1n<-nums
}
func Hepify(nums []int, unsortCapacity int) {
for i := (unsortCapacity / 2) - 1; i >= 0; i-- {
leftIndex := 2*i + 1
if leftIndex < unsortCapacity && nums[i] < nums[leftIndex] {
nums[i],nums[leftIndex] = nums[leftIndex], nums[i]
}
rightIndex := 2*i + 2
if rightIndex < unsortCapacity && nums[i] < nums[rightIndex] {
nums[i],nums[rightIndex] = nums[rightIndex], nums[i]
}
}
}
func main() {
defer fmt.Println("heap sort complete")
cha1n := make(chan []int)
var array = []int{10, 2, 7, 9, 4, 11}
go HeapSort(cha1n, array)
fmt.Println(<-cha1n)
}
总结
在学习中 我了解到算法的重要,以后的学习算法的过程中不仅只是看理论 要着重于写。在设计算法的时候要根据不同情况选择不同的策略,取长补短。