排序算法-堆排序

堆排序是一种基于二叉堆(Binary Heap)数据结构的比较排序算法。它利用了堆这种数据结构的特性来进行排序,是一种选择排序的改进版本。

堆排序的基本思想

  1. 将待排序序列构建成一个堆(大顶堆或小顶堆)

  2. 将堆顶元素(最大值或最小值)与末尾元素交换

  3. 缩小堆的范围,重新调整堆结构

  4. 重复上述过程直到整个序列有序

堆排序的特点

  • 不稳定排序:相同值的元素可能会改变相对顺序

  • 原地排序:不需要额外的存储空间(除了递归或迭代使用的栈空间)

  • 时间复杂度:始终为O(n log n),没有最坏情况

  • 空间复杂度:O(1)

代码实现

java 复制代码
package Sort;

public class HeapSort {
    public static void main(String[] args) {
        int[] res = getHeapSort(new int[]{5,8,9,1,3,6,4,2,7});
        for (int i = 0; i < res.length; i++) {
            System.out.print(res[i]+" ");
        }
    }
    //堆排序
    //步骤:
    //1.构建二叉堆(可最大堆--升序,最小堆--降序)
    //2.循环将首位元素与未排序的末尾元素交换
    //3.重新调整二叉堆

    public static int[] getHeapSort(int[] array){
        int len = array.length;
        if (len < 1) return array;
        //1.构建最大堆
        buildMaxHeap(array,len);
        //2.循环将首位(最大值)元素与未排序的末尾元素交换
        while(len > 0){
            swap(array,0,len-1);
            len--;
            //3.重新调整最大堆
            adjustHeap(array,0,len);
        }
        return array;
    }
    //1.构建二叉堆--最大堆
    public static void buildMaxHeap(int[] array,int len){
        //从最后一个非叶子结点开始向上构造最大堆,完全二叉树的非叶子结点公式:(N/2)-1
        for (int i = (len/2 - 1); i >=0 ; i--) {
            adjustHeap(array,i,len);
        }
    }
    //2.交换元素
    public static void swap(int[] array,int i,int j){
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    //3.调整二叉堆
    public static void adjustHeap(int[] array, int i, int len){
        int maxIndex = i;//定义最大指针
        //完全二叉树求左节点的公式:2*i+1, 右节点:2*i+2
        int left = 2*i + 1;
        int right = 2*i + 2;
        //如果有左子树,且左子树>父节点,则将最大指针指向左子树
        if (left < len && array[left] > array[maxIndex]){
            maxIndex = left;
        }
        //如果有右子树,且右子树>父节点,且>左子树,则将最大指针指向右子树
        if (right < len && array[right] > array[maxIndex]){
            maxIndex = right;
        }
        //如果父节点不是最大值,则将父节点与最大值交换,并且递归调整与父节点交换的位置
        if (maxIndex != i){
            swap(array,maxIndex,i);
            adjustHeap(array,maxIndex,len);
        }
    }
}

时间复杂度分析

  • 建堆过程:O(n)

  • 每次调整堆:O(log n),共需要调整n-1次

  • 总时间复杂度:O(n log n)

空间复杂度分析

堆排序是原地排序算法,只需要常数级别的额外空间,因此:

  • 空间复杂度:O(1)
相关推荐
别动我齐刘海4 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
code2cat6 小时前
Java进阶篇之AtomicLongFieldUpdater:把累计额度留在对象字段中
java·cas·并发编程
WeiXin_DZbishe6 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
泡茶喝茶写代码6 小时前
A股量化数据工程:从 REST 接口到策略信号(第 18 篇):放量缩量异动扫描
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
wewowilling6 小时前
认识微服务
java·运维·微服务·springcloud
代码什么用6 小时前
Java Web 7-10
java·servlet
蜗牛互联网8 小时前
GPT-6 与 Intelligent UI:从回答到可审计操作的产品迁移
java·人工智能·后端
SL_staff9 小时前
运维救火实录:钉钉考勤API变更引发工资计算异常,我们用JVS-Logic可视化逻辑引擎实现分钟级热修复
java·mysql·全栈
SunnyDays10119 小时前
Java 查找并高亮 Word 文字:精确查找及正则表达式模糊查找
java·查找文字·word 文档·高亮文字·正则匹配查找·模糊查找