算法练习 - 排序

排序

归并排序(分治) - 递归
  1. 终止条件 - 列表为1个
  2. 分区、一分为二
  3. 递归左边、右边
  4. 合并 - 新建立一个列表 将左边与右边两个列表对比、小的先加入
快速排序(分治) - 相当于每次为pivot 进行交换到指定位置
  1. 终止条件 - 开始位置与结束位置相等
  2. 获取一个基准点 pivot 进行分区交换、左边值小于 pivot,右边值大于 pivot,交换后pivot 就在它所属的位置了
  3. 递归 左边 left pivot-1
  4. 递归 右边 pivot+1 right
计数排序
  1. 获取最大值与最小值
  2. 建立中间值的索引列表、用i-min当索引,出现次数为值
  3. 新建立一个列表存储返回值、for 依次循环索引列表添加、值:i+min 注意点次数--。
冒泡排序
  1. 嵌套循环,维护虚拟有序列表、最大值放在右边、
  2. 当前节点与下一个节点对比、选择大的往后放
选择排序(在无序列表中找最小值)
  1. 嵌套循环、寻找后续节点中最小的元素进行交换
插入排序(在有序列表中寻找节点插入位置)
  1. 维护一个虚拟有序列表, 循环节点前有序,从第一个元素开始循环、
  2. 寻找当前值在有序列表内的位置、与上一个对比、小于则交换
冒泡排序
go 复制代码
// 两层循环比较 把最大的值放到最后, 前面无序、后面有序

func bubbleSort(nums []int) {
    for i := 0; i < len(nums); i++ {
       // 增加标志位, 未发生交换提前退出
       swap := false
       for j := 0; j < len(nums)-i-1; j++ {
          if nums[j] > nums[j+1] {
             nums[j], nums[j+1] = nums[j+1], nums[j]
             swap = true
          }
       }
       if !swap {
          break
       }
    }
}
选择排序
go 复制代码
// 两层循环、i前面为有序列表、后面为无序,每次在无序内寻找最小值进行交换
func selectSort(nums []int) {
    for i := 0; i < len(nums); i++ {
       x := i
       for j := i + 1; j < len(nums); j++ {
          if nums[j] < nums[x] {
             x = j
          }
       }
       nums[i], nums[x] = nums[x], nums[i]
    }
}
插入排序
go 复制代码
// 前有序, 后无序, 查找 i 插入的位置,j+1(j) 与 i (j+1) 进行交换
func insertSort(nums []int) {
    for i := 1; i < len(nums); i++ {
       j := i - 1
       val := nums[i]
       for j >= 0 && nums[j] > val {
          nums[j+1] = nums[j]
          j--
       }
       nums[j+1] = val
    }
}
归并排序
go 复制代码
// 分治
// 把列表一分二位进行递归, 结束条件为只剩一位进行返回
// 合并 - 把两个已排序的有序列表进行合并
func mergeSort(nums []int) []int {
    if len(nums) <= 1 {
       return nums
    }

    mid := len(nums) / 2
    left := mergeSort(nums[:mid])
    right := mergeSort(nums[mid:])

    return merge(left, right)
}

func merge(left []int, right []int) []int {
    ans := make([]int, 0, len(left)+len(right))
    i, j := 0, 0

    for i < len(left) && j < len(right) {
       if left[i] > right[j] {
          ans = append(ans, right[j])
          j++
       } else {
          ans = append(ans, left[i])
          i++
       }
    }

    ans = append(ans, left[i:]...)
    ans = append(ans, right[j:]...)
    return ans
}
快排
go 复制代码
// 交换排序
// 获取一个基点, 最后一个值进行分区
// 基点左边的值都小于, 右边的值都大于它
func quickSort(nums []int, left, right int) {
    if left >= right {
       return
    }

    pivot := partition(nums, left, right)

    quickSort(nums, left, pivot-1)
    quickSort(nums, pivot+1, right)

}

func partition(nums []int, left, right int) int {
    counter, pivot := left, right
    for i := left; i < len(nums); i++ {
       if nums[i] < nums[pivot] {
          nums[i], nums[counter] = nums[counter], nums[i]
          counter++
       }
    }
    nums[counter], nums[pivot] = nums[pivot], nums[counter]
    return pivot
}
堆排序
go 复制代码
func heapSort(nums []int) {
    h := &minHeap{}
    heap.Init(h)
    for i := 0; i < len(nums); i++ {
       heap.Push(h, nums[i])
    }

    for i := 0; i < len(nums); i++ {
       nums[i] = heap.Pop(h).(int)
    }
}

type minHeap struct {
    sort.IntSlice
}

func (m *minHeap) Push(x any) {
    m.IntSlice = append(m.IntSlice, x.(int))
}

func (m *minHeap) Pop() any {
    v := m.IntSlice[len(m.IntSlice)-1]
    m.IntSlice = m.IntSlice[:len(m.IntSlice)-1]
    return v
}
计数排序
go 复制代码
func counterSort(nums []int) []int {
    if len(nums) == 0 {
       return nums
    }

    // 获取最大值与最小值
    maxIndex, minIndex := nums[0], nums[0]
    for _, num := range nums {
       if num > maxIndex {
          maxIndex = num
       }
       if num < minIndex {
          minIndex = num
       }
    }

    // 建立计数索引、统计每个值出现的次数
    counts := make([]int, maxIndex-minIndex+1)
    for _, num := range nums {
       counts[num-minIndex]++
    }

    out := make([]int, len(nums))
    index := 0
    for i, count := range counts {
       for count > 0 {
          out[index] = i + minIndex
          index++
          count--
       }
    }

    return out
}

推荐阅读 描述很详细 - 有动画

相关推荐
飞鸟吟1 天前
【数据结构与算法】——堆(补充)
c语言·数据结构·算法·排序算法
Murphy_lx1 天前
排序(1)
数据结构·算法·排序算法
BS_Li1 天前
八大排序算法
数据结构·算法·排序算法
勤劳的进取家3 天前
贪心算法之最小生成树问题
数据结构·python·算法·贪心算法·排序算法·动态规划
扫地僧0093 天前
【中大厂面试题】腾讯 后端 校招 最新面试题
java·数据结构·后端·算法·面试·排序算法
风掣长空4 天前
八大排序——c++版
数据结构·算法·排序算法
_x_w4 天前
【12】数据结构之基于线性表的排序算法
开发语言·数据结构·笔记·python·算法·链表·排序算法
顾一大人4 天前
Python常用排序算法
python·算法·排序算法
Dovis(誓平步青云)4 天前
【数据结构】排序算法(下篇·终结)·解析数据难点
c语言·数据结构·学习·算法·排序算法·学习方法·推荐算法