选择排序(直接选择排序、堆排序)

选择排序的基本方法:
每次都从待排序对象中选出排序码最大或最小的对象,依次排列,一共进行n-1次即可将n个对象排序完成。
选择排序的实施方案:
1. 直接选择排序
2. 堆排序

 

一、直接选择排序
1. 算法代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 直接选择排序
**/
func SelectSort(data []int) {
    for i := 0; i < len(data)-1; i++ {
        minIndex := i //保存最小值的索引
        for j := i + 1; j < len(data); j++ {
            if data[j] < data[minIndex] {
                minIndex = j
            }
        }
        if minIndex != i {
            data[minIndex], data[i] = data[i], data[minIndex]
        }
    }
}

2. 时间复杂度:O(n*n)
缺陷:每次都要从n-i+1个记录中选一个排序码最小的对象,从而需要进行n-i次比较,当n很大时,其效率很低。
3. 稳定性:不稳定

 

二、堆排序
关于堆的介绍与实现可以先查看我的另一篇博文:https://www.cnblogs.com/wujuntian/p/12286502.html
1. 算法描述:
使用最小堆或最大堆来选出待排序对象的最小或最大排序码对象。
2. 算法代码:
可以使用最小堆或者最大堆实现,其中使用最大堆算法的空间复杂度更优,因为只需在原来数组上对数据位置进行调整即可,而使用最小堆排序的话还需要使用一个额外的数组来存储排序结果。所以这里只给出使用最大堆的算法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* 堆排序(使用最大堆)
**/
func HeapSort(data []int) {
    count := len(data)                      //最大堆数据个数
    for i := (count - 2) / 2; i >= 0; i-- { //从拥有孩子节点的最后一个父节点开始,向下调整,初始化最大堆
        shiftDown(data, i, count-1)
    }
    for count > 1 {
        data[0], data[count-1] = data[count-1], data[0] //将堆顶元素与最后一个元素交换位置
        count--                                         //最大堆数据个数减少
        shiftDown(data, 0, count-1)                     //向下调整最大堆
    }
}
 
/**
* 向下调整最大堆
**/
func shiftDown(data []int, start, end int) {
    i, j := start, start*2+1 //j为i的左孩子
    temp := data[i]
    for j <= end {
        if j+1 <= end && data[j+1] > data[j] { //取左右孩子的最大值
            j++
        }
        if data[j] > temp { //孩子比父节点大,交换数值,继续向下调整
            data[i] = data[j]
            i, j = j, j*2+1
        } else {
            break
        }
    }
    data[i] = temp
}

3. 时间复杂度:O(nlogn)
直接选择排序进行了很多重复的比较,而堆则相当于保存了比较结果,避免太多重复比较,所以比较次数较少,但是由于建立初始堆所需的比较次数较多,所以堆排序对记录数较少的序列并不值得提倡,但对于数目较大的序列来说还是很有效的。
4. 空间复杂度:O(1)
5. 稳定性:不稳定

posted @   疯一样的狼人  阅读(359)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2017-02-13 MySQL查询性能优化
点击右上角即可分享
微信分享提示