【408数据结构与算法】—堆排序(二十一)

简介: 【408数据结构与算法】—堆排序(二十一)

一、堆的定义

从堆的定义可以看出,堆实质是满足如下性质的完全二叉树,二叉树中任一非叶子结点均小于(大于)它的孩子结点

C语言代码实现

#include <stdio.h>
#include <malloc.h>
void HeapAdjust(int a[],int s,int m)//一次筛选的过程
{
    int rc,j;
    rc=a[s];
    for(j=2*s;j<=m;j=j*2)//通过循环沿较大的孩子结点向下筛选
    {
        if(j<m&&a[j]<a[j+1]) j++;//j为较大的记录的下标
        if(rc>a[j]) break;
        a[s]=a[j];s=j;
    }
    a[s]=rc;//插入
}
void HeapSort(int a[],int n)
{
    int temp,i,j;
    for(i=n/2;i>0;i--)//通过循环初始化顶堆
    {
        HeapAdjust(a,i,n);
    }
    for(i=n;i>0;i--)
    {
        temp=a[1];
        a[1]=a[i];
        a[i]=temp;//将堆顶记录与未排序的最后一个记录交换
        HeapAdjust(a,1,i-1);//重新调整为顶堆
    }
}
int main()
{
    int n,i;
    scanf("%d",&n);
    int a[n+1];
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    HeapSort(a,n);
}

判断是否是堆?

二、堆排序

若在输出堆顶的最小值(最大值)后,使得剩余n-1 个元素的序列重新建成一个堆,则得到n个元素的次小值(次大值)如此反复,便能得到一个有序序列,这个过程称为堆排序

三、实现堆排序需要解决两个问题

(一)、如何在输出堆顶元素后,调整剩余元素为一个新的堆?

小根堆

  • 输出堆顶元素之后,以堆中的最后一个元素替代
  • 然后将根结点值与左、右子树的根结点值进行比较,并与其中小者进行交换
  • 重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为筛选。

堆的调整

筛选过程的算法描述为

从以上代码可以看出:对于一个无序序列反复筛选就可以得到一个堆即从一个无序序列建堆的过程就是一个反复筛选的过程

(二)、如何由一个无序序列建成一个堆?

😛堆的建立

  • 显然单结点的二叉树是堆;
  • 在完全二叉树中所有以子节点(序号i>n/2)为根的子树是堆

由于堆实质是一个线性表,那么我们可以顺序存储一个堆

例如:有关键字为49,38,65,97,76,13,27,49的一组记录,将其按关键字调整为一个小根堆

由以上分析知:

若一个无序序列建堆,然后输出根,重复该过程就可以由一个无序序列输出有序序列

实际上,堆排序就是利用完全二叉树中父结点与孩子结点之间的内在关系来排序的。

堆排序算法

算法性能分析:

  • 初始化时间不超过O(n)
  • 堆排序的时间主要耗费在建初始堆和调整建新堆时进行的反复筛选上,堆排序在最坏的情况下,其时间复杂度为O(nlog2n),这是堆排序的最大优点。无论待排序列还是逆序排列,都不会使堆排序处于最好或最坏的状态。
  • 另外,堆排序仅需一个记录大小交换用的辅助存储空间
  • 然而堆排序是一种不稳定的排序方法,它不是适用于待排序记录个数 n较少的情况,但对于n较大的文件还是很有效的。


相关文章
|
8天前
|
机器学习/深度学习 人工智能 算法
数据结构与算法:堆排序和TOP-K问题
朋友们大家好,本节内容来到堆的应用:堆排序和topk问题
数据结构与算法:堆排序和TOP-K问题
|
8天前
|
算法
数据结构——堆的应用 堆排序详解
数据结构——堆的应用 堆排序详解
数据结构——堆的应用 堆排序详解
|
8天前
|
移动开发 算法 前端开发
前端算法之堆排序
前端算法之堆排序
15 1
|
2天前
|
算法 搜索推荐
数据结构与算法⑫(第四章_中_续一)堆排序(详解)
数据结构与算法⑫(第四章_中_续一)堆排序(详解)
9 0
|
8天前
【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)
【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)
19 4
|
8天前
|
人工智能 搜索推荐 算法
sort-04-heap sort 堆排序算法详解
这是一个关于排序算法的系列文章摘要,包括了10篇关于不同排序算法的链接,如冒泡排序、快速排序、选择排序、堆排序等。堆排序是一种基于比较的排序算法,利用了近似完全二叉树的结构并满足最大堆或最小堆的性质。最大堆中,每个节点的值都大于或等于其子节点。文章详细解释了最大堆的概念、节点访问方式以及堆的操作,包括堆调整和堆排序的过程,并通过图解展示了堆排序的具体步骤。此外,还提供了一个Java实现的堆排序代码示例。整个排序系列来源于一个开源项目,读者可以通过链接查看完整内容。
sort-04-heap sort 堆排序算法详解
|
8天前
|
人工智能 算法 搜索推荐
直接插入排序、希尔排序、直接选择排序、堆排序、冒泡排序——“数据结构与算法”
直接插入排序、希尔排序、直接选择排序、堆排序、冒泡排序——“数据结构与算法”
|
8天前
|
算法
堆排序+TopK问题——“数据结构与算法”
堆排序+TopK问题——“数据结构与算法”
|
8天前
|
存储 机器学习/深度学习 算法
初阶数据结构之---堆的应用(堆排序和topk问题)
初阶数据结构之---堆的应用(堆排序和topk问题)
|
8天前
|
算法 搜索推荐 数据挖掘
【算法与数据结构】堆排序&&TOP-K问题
【算法与数据结构】堆排序&&TOP-K问题