堆排序,顾名思义,是采用数据结构堆来进行排序的一种排序算法。

研究没有规律的堆,没有任何意义。特殊的堆有最大堆(父节点值大于等于左右字节点值),最小堆(父节点值小于等于子节点值)。一般采用最大堆来进行排序,图1为最大堆来表示一维数组。

图1 最大堆表示一维数组

2叉树堆的几点特性

1、 最后父节点索引值

不妨设堆的总元素个数为N;最后一个父节点的索引值Index = N/2 ;可以写几个简单的堆进行数学归纳。图1中的最后一个父节点5 = 10 /2 ;

这个特性主要是在采用自底向上构建堆的时候,循环起始值。

2、父节点与子节点索引值关系

LeftIndex = parent * 2;

RightIndex = parent * 2 + 1;

对于任意一个节点K,其父节点为K/2,其左子节点为2K,右子节点为2K+1。

Max-Heapify(保持最大堆属性)

散乱排布的堆对算法的实现非常不友好,没有意义。因此,在随机数据输入时,需要对数据按照最大堆的属性进行一个初始排序。对一个父节点数据的max-heapify形象的推导直接采用算法导论的图,如图2。节点2的数据显然不符合最大堆的数据定义(父节点值不小于子节点值),因此把MAX(parent,left,right)替换到父节点,父节点的数据替换 到子节点中。对于替换的子节点4,仍然需要判断其是否满足最大堆数据定义,一直递归到满足定义。

图2 max-heapify原理

构建最大堆

对所有的父节点都进行max-heapify操作,自底向上从最后父节点一直循环到根节点,很巧妙。采用自底向上能够保证遍历过的数据始终是保持最大堆属性的,max-heapify操作始终是求当前父节点下所有子节点的最大值。

那自顶向下会怎样呢?

第一次max-heapify后,根节点并没有变成最大值,还要再遍历下根节点,这个显然在算法设计上不合适。所以自底向上的构思很巧妙。

HeapSort

首先保证输出数据满足最大堆的数据属性(第一行),然后把最大值提取出来存储在数组末端;然后计算剩下数据的最大堆,把最大值提出来;循环操作到排序完成。采用算法导论图解

编程实现

void CHeapSort::maxHeapify( std::vector<int> &arrayA, int index )
{ int l = leftChild(index);
int r = rightChild(index); int maxValue = ; if(l < heapSize && arrayA[l] > arrayA[index])
{
maxValue = l;
}
else
{
maxValue = index;
} if(r < heapSize && arrayA[r] > arrayA[maxValue])
{
maxValue = r;
} /* 父节点部位最大值 */
if(maxValue != index)
{
std::swap(arrayA[index],arrayA[maxValue]);
maxHeapify(arrayA,maxValue);
} } void CHeapSort::buildMaxHeap( std::vector<int> &arrayA )
{
heapSize = arrayA.size();
int halfSize = heapSize >> ; for(int i = halfSize ;i >= ; i--)
{
maxHeapify(arrayA,i);
}
} void CHeapSort::heapSort( std::vector<int> &arrayA )
{
buildMaxHeap(arrayA); for(int i = arrayA.size() - ; i > ; i--)
{
std::swap(arrayA[],arrayA[i]);
heapSize--;
maxHeapify(arrayA,);
}
}

结果:

  

堆排序HeapSort的更多相关文章

  1. 堆排序 Heapsort

    Prime + Heap 简直神了 时间优化好多,顺便就把Heapsort给撸了一发 具体看图 Heapsort利用完全二叉树+大(小)顶锥的结构每次将锥定元素和锥最末尾的元素交换 同时大(小)顶锥元 ...

  2. 排序算法FOUR:堆排序HeapSort

    /** *堆排序思路:O(nlogn) * 用最大堆,传入一个数组,先用数组建堆,维护堆的性质 * 再把第一个数与堆最后一个数调换,因为第一个数是最大的 * 把堆的大小减小一 * 再 在堆的大小上维护 ...

  3. 算法分析-堆排序 HeapSort 优先级队列

    堆排序的是集合了插入排序的单数组操作,又有归并排序的时间复杂度,完美的结合了2者的优点. 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki < ...

  4. 堆排序——HeapSort

    基本思想:   图示: (88,85,83,73,72,60,57,48,42,6)   平均时间复杂度: O(NlogN)由于每次重新恢复堆的时间复杂度为O(logN),共N - 1次重新恢复堆操作 ...

  5. 堆排序Heapsort的Java和C代码

    Heapsort排序思路 将整个数组看作一个二叉树heap, 下标0为堆顶层, 下标1, 2为次顶层, 然后每层就是"3,4,5,6", "7, 8, 9, 10, 11 ...

  6. 堆排序与优先队列——算法导论(7)

    1. 预备知识 (1) 基本概念     如图,(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树.树中的每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且从左向右填充.堆的数组 ...

  7. 堆排序算法 java 实现

    堆排序算法 java 实现 白话经典算法系列之七 堆与堆排序 Java排序算法(三):堆排序 算法概念 堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特 ...

  8. 排序 选择排序&&堆排序

    选择排序&&堆排序 1.选择排序: 介绍:选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始 ...

  9. 排序算法——QuickSort、MergeSort、HeapSort(C++实现)

    快速排序QuickSort template <class Item> void quickSort (Item a[], int l, int r) { if (r<=l) ret ...

随机推荐

  1. 【转】Wi-Fi 20mhz 和 40mhz 频段带宽的区别是什么?

    一.无线网卡模式 wifi现在市场上主要存在802.11a/b/g/n/ac五种模式的无线网卡: 1.b的最大速率11Mbps,频段2.4G,带宽22M: 2.a的最大速率54Mbps,频段5G,带宽 ...

  2. HDU1081 最大字段和 压缩数组

    最大字段和题型,推荐做题顺序: HDU1003    HDU1024     HDU1081  zoj2975  zoj2067 #include<cstdio> #include< ...

  3. zoj 2022

    分析: 组合数学类型的题目. 正常的话可能会去分解1~N数里面有几个5和2,但是这样的复杂度为O(nlogn). 其实有更巧妙的办法,可以把问题分解成子问题. 可以发现N!末尾的0与1~N中有几个5的 ...

  4. 远程连接MySQL,防火墙阻止访问,解决方法

    远程连接MySQL,防火墙阻止访问,解决方法   xp/2003添加防火墙例外端口 打开防火墙,选择例外选项卡,添加端口 名称:mysqlport 端口号:3306 选中TCP win7添加防火墙例外 ...

  5. 记录一次因为硬盘写满造成的redis无法连接

    缘起: 今天早晨收到报警,服务不干活了,赶紧起来看问题... 为了尽快让服务可用,尝试重启服务,发现服务起不来,报错 redis connection failed! 看起来是redis挂了,但是发现 ...

  6. java优雅的使用elasticsearch api

    本文给出一种优雅的拼装elasticsearch查询的方式,可能会使得使用elasticsearch的方式变得优雅起来,使得代码结构很清晰易读. 建立elasticsearch连接部分请参看另一篇博客 ...

  7. PE格式第七讲,重定位表

    PE格式第七讲,重定位表 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 一丶何为重定位(注意,不是重定位表格) 首先, ...

  8. CVPixelBuffer的创建 数据填充 以及数据读取

    CVPixelBuffer的创建数据填充以及数据读取 CVPixelBuffer 在音视频编解码以及图像处理过程中应用广泛,有时需要读取内部数据,很少的时候需要自行创建并填充数据,下面简单叙述. 创建 ...

  9. CMake必知必会

    CMake 文档 https://cmake.org/cmake/help/v3.7/index.html 需要阅读的文档 item note link cmake-buildsystem(7) cm ...

  10. 解析 .Net Core 注入 (2) 创建容器

    在上一节的学习中,我们已经知道了通过 IServiceCollection 拓展方法创建 IServiceProvider 默认的是一个类型为 ServiceProvider 对象,并且实际提供创建对 ...