【排序算法】堆排序详解与实现

简介: 【排序算法】堆排序详解与实现

一、堆排序的思想

      堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆(若不清楚什么是堆,可以看我前面的文章,有详细阐述)来进行选择数据,通过向下调整算法,从第一个非叶子结点开始在局部先创建出大堆(或小堆),然后父亲结点不断往上走,直到整棵树都建成一个堆 需要注意的是排升序要建大堆,排降序建小堆。( 然后不断交换根节点和最后一个节点的值,交换完后节点的数目减1(因为最后一个节点已经是它应该在的位置了,不用再参与建堆),再从根节点向下建堆(除最后一个节点其它节点又会建成一个堆) 然后重复红色括号中的过程,堆排序就完成了。

二、堆排序的图解

下图以建大堆为例排一个升序序列

三、堆排序的实现

3.1向下调整算法的实现

实现堆排序最重要的就是实现向下调整算法。以下是向下调整算法的代码以及解释

//这里以建大堆为例
void AdjustDown(int* a, int n, int root)
{
  int child = root * 2 + 1;//找到根节点的左孩子
  while (child < n)//判断左孩子是否出界
  {
    if (child + 1 < n && a[child + 1] > a[child])
      //child + 1 < n判断右孩子是否出界,
      //a[child + 1] > a[child]判断左右孩子的大小,取左右孩子中大的那一个
      child++;
    if (a[child] > a[root])//入过孩子的值比父亲的值大,就交换孩子和父亲的位置
      Swap(&a[child], &a[root]);
    else//如果孩子的值不比父亲的值大,就证明大堆已经建好了(因为此时父亲的左右子树都是大堆),
      //直接break跳出循环。
      break;
    //没有break来到这里就顺着子树继续往下走
    root = child;
    child = root * 2 + 1;
  }
}

3.2堆排序的实现

以下是堆排序的代码实现以及解释

void HeapSort(int* a, int n)
{
  //向下调整建堆
  for (int i = (n - 1 - 1) / 2; i >= 0; i--)
  {
    //(n - 1 - 1) / 2找到第一个非叶子节点,从第一个非叶子结点开始向下建堆
    AdjustDown(a, n, i);
  }
  //堆建好了
  int end = n - 1;
  while (end > 0)
  {
    //假设是建大堆,将下标为0的元素和下标为end的元素交换,
    //最大的数就排到最后了,也就相当于最后的那个数已经排好了,不用再参与下面的向下建堆
    Swap(&a[0], &a[end]);
    AdjustDown(a, end, 0);//还没有排好的数向下建堆从0位置开始向下建堆
    end--;
  }
}

四、总结

堆排序的时间复杂度为 O(N*logN) (向下建堆时间复杂度为O(N),排序时间复杂度为O(N*logN)), 空间复杂度:O(1) ,稳定性:不稳定。

相关文章
|
5月前
|
算法 Python
数据结构算法--4堆排序
堆排序过程概述:建立大根堆,将堆顶最大元素移出并替换为末尾元素,调整保持堆性质,重复此过程直至堆为空,实现排序。时间复杂度为O(nlogn)。Python中可用heapq模块进行堆操作。
|
6月前
|
机器学习/深度学习 人工智能 算法
数据结构与算法:堆排序和TOP-K问题
朋友们大家好,本节内容来到堆的应用:堆排序和topk问题
数据结构与算法:堆排序和TOP-K问题
|
6月前
|
存储 人工智能 算法
深入浅出堆排序: 高效算法背后的原理与性能
深入浅出堆排序: 高效算法背后的原理与性能
117 1
|
1月前
|
算法 搜索推荐
数据结构与算法学习十八:堆排序
这篇文章介绍了堆排序是一种通过构建堆数据结构来实现的高效排序算法,具有平均和最坏时间复杂度为O(nlogn)的特点。
70 0
数据结构与算法学习十八:堆排序
|
1月前
|
算法 搜索推荐
算法之堆排序
本文介绍了堆排序算法的原理和实现,通过构建最大堆或最小堆,利用堆的性质进行高效的排序,并提供了具体的编程实现细节和示例。
21 0
算法之堆排序
|
1月前
|
算法 Java Go
深入了解堆排序算法
深入了解堆排序算法
23 1
|
6月前
|
移动开发 算法 前端开发
前端算法之堆排序
前端算法之堆排序
41 1
|
5月前
|
搜索推荐 算法 Java
Java中的快速排序、归并排序和堆排序是常见的排序算法。
【6月更文挑战第21天】Java中的快速排序、归并排序和堆排序是常见的排序算法。快速排序采用分治,以基准元素划分数组并递归排序;归并排序同样分治,先分割再合并有序子数组;堆排序通过构建堆来排序,保持堆性质并交换堆顶元素。每种算法各有优劣:快排平均高效,最坏O(n²);归并稳定O(n log n)但需额外空间;堆排序O(n log n)且原地排序,但不稳定。
47 3
|
5月前
|
搜索推荐 算法
【C/排序算法】:堆排序和选择排序
【C/排序算法】:堆排序和选择排序
34 0
|
5月前
|
存储 算法 C语言
数据结构和算法——堆排序(选择排序、思路图解、代码、时间复杂度、堆排序及代码)
数据结构和算法——堆排序(选择排序、思路图解、代码、时间复杂度、堆排序及代码)
36 0
下一篇
无影云桌面