首页 > 编程语言 >常用的排序算法

常用的排序算法

时间:2023-08-12 15:55:38浏览次数:31  
标签:常用 end int arr len 算法 func 排序

总结

image

基于比较的排序(从小到大排序)

冒泡排序

GO实现
func MySort( arr []int ) []int {
    // 冒泡
    // 大的往后冒
    for i := 0; i < len(arr); i++{
        for j := 0; j < len(arr) - 1 - i; j++ {
            if arr[j] > arr[j + 1]{
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
            }
        }
    }
    return arr
}
另一种实现
func MySort( arr []int ) []int {
    // 小的往前冒
    for i := 0; i < len(arr); i++{
        for j := len(arr) - 1; j > i ; j-- {
            if arr[j] < arr[j - 1]{
                arr[j], arr[j - 1] = arr[j - 1], arr[j]
            }
        }
    }
    return arr
}

选择排序

GO实现
func MySort( arr []int ) []int {
    // 选择排序
    // 不稳定:5 5 1
    for i := 0; i < len(arr); i++{
        minPoi := i
        for j := i + 1; j < len(arr); j++{
            if arr[minPoi] > arr[j] {
                minPoi = j
            }
        }
        arr[i], arr[minPoi] = arr[minPoi], arr[i]
    }
}

直接插入排序

GO实现
func MySort( arr []int ) []int {
    // 稳定:2 2 1
    for i := 1; i < len(arr); i++ {
        if arr[i] < arr[i - 1]{
            temp := arr[i]
            j := i - 1
            for j >= 0 && temp < arr[j] {
                arr[j + 1] = arr[j]
                j--
            }
            arr[j + 1] = temp
        }
    }
}

希尔排序(第一个突破n^2的排序算法)

GO实现
func MySort( arr []int ) []int {
    // 不稳定:相同元素不在同一组,则无法保证相对顺序
    var shell func(int, int)
    shell = func(begin, step int) {
        for i := begin + step; i < len(arr); i += step {
            if arr[i] < arr[i - step] {
                temp := arr[i]
                j := i - step
                for j >= begin && temp < arr[j] {
                    arr[j + step] = arr[j]
                    j -= step
                }
                arr[j + step] = temp
            }
        }
    }
    step := len(arr)/2
    for step > 0 {
        for i := 0; i < step; i++{
            shell(i, step)
        }
        step /= 2
    }
}

归并排序

GO实现
func MySort( arr []int ) []int {
    // 2 2 1 稳定
    if len(arr) < 2 {
        return arr
    }
    mid := len(arr)/2
    left := arr[:mid]
    right := arr[mid:]
    var merge func([]int, []int) []int
    merge = func(left []int, right []int)(ans []int){
        i := 0
        j := 0
        for i < len(left) && j < len(right){
            if left[i] <= right[j] {
                ans = append(ans, left[i])
                i++
            }else{
                ans = append(ans, right[j])
                j++
            }
        }
        ans = append(ans, left[i:]...)
        ans = append(ans, right[j:]...)
        return
    }
    return merge(MySort(left), MySort(right))
}

快速排序

GO实现
func MySort( arr []int ) []int {
    if len(arr) < 2 {
        return arr
    }
    // 2,2,1 不稳定
    var quicSort func(int, int)
    quicSort = func(begin, end int) {
        if(end - begin <= 0){
            return
        }
        cur := arr[begin]
        left := begin
        right := end
        isRight := true
        for left != right {
            if isRight {
                if arr[right] < cur {
                    arr[left] = arr[right]
                    isRight = !isRight
                }else{
                    right--
                }
            } else {
                if arr[left] > cur {
                    arr[right] = arr[left]
                    isRight = !isRight
                }else{
                    left++
                }
            }
        }
        arr[left] = cur
        quicSort(begin, left - 1)
        quicSort(left + 1, end)
    }
    quicSort(0, len(arr) - 1)
}

堆排序

有两种建堆方式:从顶向下O(n)(已知堆的大小),从底向上O(nlogn)(堆的大小动态调整)
参考博文:【堆/排序】堆排序的两种建堆方法

GO实现
func MySort( arr []int ) []int {
    if len(arr) < 2 {
        return arr
    }
    // 不稳定 2 2 1
    // 从小到大排序,用大顶堆,每次把根节点放最后,然后end - 1
    var down func(int, int) 
    down = func(start int, end int){
        for start < end {
            fmt.Println(start)
            left := 2 * start + 1
            right := 2 * start + 2
            if left > end {
                break
            }
            max := arr[left]
            if right <= end && arr[right] > max{
                max = arr[right]
            }
            if max > arr[start] {
                if max == arr[left] {
                    arr[start], arr[left] = arr[left], arr[start]
                    start = left
                } else {
                    arr[start], arr[right] = arr[right], arr[start]
                    start = right
                }
            }else{
                break
            }
        }
    }
    end := len(arr) - 1
    // 先建堆
    // end的父节点是:(end - 1)/2
    for i := (end - 1)/2; i >= 0; i-- {
        down(i, end)
    }
    fmt.Println(arr[end])
    // 再排序
    for end >= 1 {
        arr[0], arr[end] = arr[end], arr[0]
        end--
        down(0, end)
    }
}

非比较排序(基于桶排序思想)

计数排序(适合数据跨度小,重复数据多的情况)

相当于为每个数字安排一个桶

GO实现
func MySort( arr []int ) []int {
    if len(arr) < 2 {
        return arr
    }
    minArr := math.MaxInt
    maxArr := -1
    for _, v := range arr {
        if minArr > v {
            minArr = v
        }
        if maxArr < v {
            maxArr = v
        }
    }
    record := make([]int, maxArr - minArr + 1)
    for _, v := range arr {
        record[v - minArr]++
    }
    cur := 0
    for i, v := range record {
        for v > 0 {
            arr[cur] = i + minArr
            cur++
            v--
        }
    }
}

基数排序(桶排序的变种)

一位一位的来处理数据,桶的数量固定为十个,桶间有序,桶内无序。
有两种处理方式:

  • 从最高位到最低位:每个桶内要再进行桶排序
  • 从最低位到最高位:只要调用最大数的最高位数次排序就行
GO实现
func MySort( arr []int ) []int {
    if len(arr) < 2 {
        return arr
    }
    // 找到最大值
    maxValue := -1
    for _, v := range arr {
        if maxValue < v {
            maxValue = v
        }
    }
    // 找到最高位
    maxBit := 0
    for maxValue != 0 {
        maxValue /= 10
        maxBit++
    }
    // fmt.Println(maxBit)
    // 声明十个桶
    buckets := make([][]int, 10)
    base := 1
    for i := 0; i < maxBit; i++ {
        for _, v := range arr {
            buckets[(v / base) % 10] = append(buckets[(v/base)%10], v)
        }
        index := 0
        for j, bucket := range buckets {
            if len(bucket) == 0 {
                // fmt.Println(len(bucket))
                continue
            }
            for _, v := range bucket{
                arr[index] = v
                index++
            }
            // 清空桶
            buckets[j] = buckets[j][:0]
        }
        base *= 10
    }
    return arr
}
tips

是不是很疑惑我为什么没写桶排序?

  • 要使用桶排序算法,首先要确定桶的数量,这一点就很麻烦
  • 由于桶内是无序的,所以往往还需要在桶内调用快排之类的基于比较的排序算法,所以我个人觉得桶排序不能算非比较排序,所以没有写

标签:常用,end,int,arr,len,算法,func,排序
From: https://www.cnblogs.com/01cainiao/p/17624926.html

相关文章

  • git常用的命令
    一.克隆git上的项目1.1克隆git上的主分支项目gitclone项目链接1.1克隆git上的其他分支项目标题:SQLServer导入和导出向导------------------------------操作无法完成。------------------------------其他信息:------------------------------按钮:确定......
  • linux中常用端口查询命令
    1、lsof-i:80 用于查看某一端口的占用情况2、netstat-tunlp|grep80 用于查看指定的端口号的进程情况......
  • java字符串String类的常用方法
    java字符串String类的常用方法字符串的创建:(1)定义字符串直接赋值,在字符串池中开辟空间()Stringstr1=“Hello”;//在字符串池中写入字符串"hello"Stringstr2=“Hello”;//直接引用字符串池中的"Hello"System.out.println(str1==str2);//地址相同,输出:true(2)使用new关键字调用字......
  • 快速排序(NB)
    博客地址:https://www.cnblogs.com/zylyehuo/#_*_coding:utf-8_*_defpartition(li,left,right):tmp=li[left]whileleft<right:whileleft<rightandli[right]>=tmp:#从右面找比tmp小的数right-=1#往左走一步l......
  • 交换排序
    数据结构--交换排序基本思想:两两比较,如果发生逆序则交换,直到所有记录都排好序为止.冒泡排序每趟不断将记录两两比较,并且按照"前小后大"规则交换.冒泡排序的过程演示n个记录,需要比较n-1趟.第m躺需要比较n-m次冒泡排序算法描述还可以继续优化:某一趟比较时不出现......
  • 【蓝桥杯备赛系列 | 简单题】数组排序(八大排序演示)
    ......
  • 冒泡排序
    #include<iostream>usingnamespacestd;intmain(){intt,a[4];for(inti=1;i<=3;i++){cin>>a[i];}for(inti=1;i<=2;i++){for(intj=1;j<=3-i;j++){if(a[j]<a[j+1]){t......
  • pycharm常用快捷键
    pycharm常用快捷键参考:https://blog.csdn.net/pipisorry/article/details/39909057打开pycharm>help>keymapReference1、编辑(Editing)Ctrl+Space基本的代码完成(类、方法、属性)Ctrl+Alt+Space快速导入任意类Ctrl+Shift+Enter语句完成Ctrl+P参数信息......
  • a、算法的提出
    基本概念参考文档:《数据结构与算法Python语言描述_裘宗燕》B站视频:数据结构与算法(Python语言描述)--完整顺序版算法的概念算法是计算机处理信息的本质,因为计算机程序本质上是一个算法来告诉计算机确切的步骤来执行一个指定的任务。一般地,当算法在处理信息时,会从输入设备或数据......
  • 文心一言 VS 讯飞星火 VS chatgpt (74)-- 算法导论7.2 2题
    二、如果用go语言,当数组A的所有元素都具有相同值时,QUICKSORT的时间复杂度是什么?文心一言:在Go语言中,对一个所有元素都相等的数组进行快速排序(QuickSort)的时间复杂度是O(nlogn)。快速排序是一种分而治之的排序算法,它将一个数组分成两个子数组,然后对这两个子数组进行递归排序。在最......