首页 > 编程语言 >排序算法(3) 堆排序

排序算法(3) 堆排序

时间:2024-07-06 17:30:14浏览次数:20  
标签:int 元素 堆排序 算法 数组 ind 排序

堆排序

1. 算法原理

堆排序的原理与部分没听说过该排序方法的同学猜想的不同,它并不是将堆顶元素逐一弹出后压入数组中来得到一个有序的数组。这种方法在初始建堆时需要使用一个数组空间,在得到有序的数组时需要使用另一个数组空间。而堆排序则是在初始数组的基础上直接进行排序,相较于上一种方法节省了一倍的空间

堆排序的做法时:
从小到大排序数组为例,首先使用初始数组建立一个大顶堆,记作a[1…n],然后将堆顶元素a[1]与堆尾元素a[n]进行交换,将此次操作看作是一次堆顶元素弹出操作,据此调整堆数组范围和元素位置,记新堆为a[1…n - 1]。不断重复以上操作,直到堆中只剩一个元素,最终的数组便排好了序。

2. 算法模拟

对于数组:3 5 8 4 3 2 10 1 9,进行从小到大排序

在这里插入图片描述

由图可知,堆排序仅仅使用了建堆时的数组空间,最终排序结果仍存储在该数组中。

3. 线性建堆法

知道了堆排序的算法原理,但如何将一个待排序数组建成一个堆呢?

在这里简单介绍一下线性建堆法

线性建堆法的算法原理是:将当前数组看成一个完全二叉树,再将该完全二叉树从后到前一次性扫描所有拥有子节点的节点,最终将数组调整成堆。

[点击并拖拽以移动]

4. 算法分析

(1)排序稳定性:

对于数组a[1…n],假设第3~第n号元素已排序好,且a[1] = a[2],则对于第n - 1次循环,a[1]将与a[2]互换,且在第n次循环时循环结束,此时a[1]与a[2]不满足排序前的相对位置,即最终排序好的数组不满足排序稳定性,因此堆排序是不稳定的。

(2)时间复杂度:

建堆时,需要深搜遍历完全二叉树的每一个节点,并按照堆性质进行调整,即需要遍历整个数组,时间复杂度为O(n)

弹出后调整堆时,只需要对一个节点按照堆性质进行调整,即调整堆层数次数,时间复杂度为O(logn)

每次弹出后都需要进行调整,共弹出n次、调整n次。

因此,堆排序算法的时间复杂度为: O ( n log ⁡ n ) O(n\log n) O(nlogn)

5. 代码演示


// 线性建堆
int* buildheap(int n, int* a) // n为数组元素个数,a为数组,函数返回建成堆的数组
{
    for(int i = n / 2; i >= 1; --i)
    {
        int j = i;
        while(j <= n / 2) // 限定节点有子节点,不断dfs
        {
            if(a[j] < a[2 * j] || (a[j] < a[2 * j + 1] && 2 * j + 1 <= n)) // 节点向下调整
            {
                int ind = 0;
                if(a[2 * j] < a[2 * j + 1] && 2 * j + 1 <= n)
                {
                    ind = 2 * j + 1;
                }
                else
                {
                    ind = 2 * j;
                }
                swap(a[j], a[ind]);
                j = ind;
            }
            else // 节点无需向下调整,break
                break;
        }
    }
    return a;
}

// 堆排序
void heap_sort(int n, int* a) // n为数组元素个数,a为数组,函数返回排好序的数组
{
    a = buildheap(n, a);
    int num = n; // num用来控制当前堆中元素个数
    for(int i = n; i > 1; --i) // 只需执行n - 1次循环
    {
        swap(a[i], a[1]);
        num -= 1;
        if(num == 1) // 当本次循环堆中只有一个元素时,直接结束即可
            break;
        int j = 1;
        while(j <= num / 2)
        {
            if(a[j] < a[2 * j] || (a[j] < a[2 * j + 1] && 2 * j + 1 <= num))
            {
                int ind = 0;
                if(a[2 * j] < a[2 * j + 1] && 2 * j + 1 <= num)
                {
                    ind = 2 * j + 1;
                }
                else
                {
                    ind = 2 * j;
                }
                swap(a[j], a[ind]);
                j = ind;
            }
            else
                break;
        }
    }
    return;
}


标签:int,元素,堆排序,算法,数组,ind,排序
From: https://blog.csdn.net/weixin_71402055/article/details/140232530

相关文章

  • LRU算法简介
    LRU(LeastRecentlyUsed,最近最少使用)算法是一种常用于缓存管理的算法,用于在缓存空间有限的情况下,决定哪些数据应该被移除。它的基本思想是:如果一个数据最近被访问过,那么在将来一段时间内它被再次访问的概率较高。因此,当缓存已满,需要移除数据时,优先移除那些最近最少被使用的数据。......
  • LRU缓存算法设计
    LRU缓存算法的核⼼数据结构就是哈希链表,双向链表和哈希表的结合体。这个数据结构⻓这样:创建的需要有两个方法,一个是get方法,一个是put方法。一些问题:为什么需要使用双向链表呢?因为删除链表的本身,需要得到他的前一个节点。如果使用单链表,效率就会很低,这边是使用的空间换......
  • 打卡信奥刷题(251)用Scratch图形化工具信奥P9771[普及组][HUSTFC 2023] 排列排序问题
    [HUSTFC2023]排列排序问题题目描述JokerShaco有一个长度为nnn的排列pp......
  • 代码随想录算法训练营第五十六天 | 98.所有可达路径
    98.所有可达路径题目链接文章讲解邻接矩阵法邻接矩阵使用二维数组来表示图结构。邻接矩阵是从节点的角度来表示图,有多少节点就申请多大的二维数组为了节点标号和下标对其,有n个节点的图申请(n+1)*(n+1)的空间vector<vector<int>>graph(n+1,vector<int>(n+1,0)......
  • 【BP时序预测】基于布谷鸟优化算法CS实现负荷数据预测单输入单输出附matlab代码
    %负荷数据预测单输入单输出(BP时序预测)%使用布谷鸟优化算法实现%假设你已经有了输入数据和对应的输出数据%输入数据应该是一个矩阵,每一行代表一个样本,每一列代表一个特征%输出数据应该是一个列向量,每个元素代表对应样本的输出%设置布谷鸟优化算法参数max_iter=......
  • 调度系统揭秘(下):调度算法与架构设计
    一、调度算法在调度系统中,调度算法常见是以下两种:广度优先深度优先1.1、广度优先:广度优先搜索算法按照任务之间的依赖关系进行逐级遍历,先执行所有直接前置任务,再执行所有直接后继任务,以此类推,直到所有的任务都被遍历和执行完成。其特点如下:执行顺序合理:广度优先搜索保......
  • 快速排序c++&&java代码实现
    快速排序的思想(基于分治法): 每次选一个基准元素x,通过一次遍历将排序表划分为独立的两部分a[l,k-1],a[k+1,r];其中左边的元素<=x,右边的1元素>x,然后递归下去,直到每个块的大小为1;c++#include<bits/stdc++.h>usingnamespacestd;voidquickSort(vector<int>&q,int......
  • 代码随想录算法训练营第二天 | 203.移除链表元素 707.设计链表 206.反转链表
    代码随想录算法训练营第二天|203.移除链表元素707.设计链表206.反转链表进入链表章节,就要和虚拟头结点(dummyhead)打交道了,还要注意边界条件和空指针异常移除链表元素题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A......
  • 【中国算力大会分会,SPIE独立出版!AHPCAI前三届已完成EI检索!】2024算法、高性能计算与人
    2024算法、高性能计算与人工智能国际学术会议(AHPCAI2024)定于2024年8月14-16日在中国郑州举行。会议主要围绕算法、高性能计算与人工智能等研究领域展开讨论。会议旨在为从事算法、高性能计算与人工智能研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果......
  • 【matlab】分类回归——智能优化算法优化径向基神经网络
    径向基(RadialBasisFunction,RBF)神经网络一、基本概念径向基函数(RBF):是一个取值仅仅依赖于离原点(或某一中心点)距离的实值函数。在RBF神经网络中,最常用的径向基函数是高斯核函数,其形式为:其中,x​为核函数中心,σ为函数的宽度参数(或方差),控制了函数的径向作用范围。二、网络结......