Heap Sorting 总结 (C++)
各位读者,大家好。 因为算法和数据结构相关的知识都是在国外学的,所以有些词汇翻译的可能不准确,然后一些源代码的注释可能是英文的,如有给大家带来什么不方便,请见谅。今天我想写一下Heap相关的知识,从基本的结构到最后的一些常用functions. Heap 的数据结构其实可以看成Array, 例如a[] = {5,3,6,8,2,1,0}这个数组, 我们可以将其看作如下的结构:

Heap又可以分成2种类型:Max-Heap 和 Min-Heap。 Max-Heap的意思是每一个node的key值都要大于它的children的key值;反之Min-Heap的的结构是每个node的key值都小于它的children的key值。 例如一个Max-Heap的结构如下:

对于以上的Heap 数据结构的分析,可以分析出对于一个含有N个元素的heap或者称之为array,其heap的结构的的高度(level)是1+logN. 例如上面的结构就是1+log7 = 3 层。
如果一个heap当中只有一个element破坏了Max-heap/Min-Heap structure的结构,那么如果希望重构这个heap让其重新维持Max/Min的话,这个element需要跟它的children中的较大的值交换,一直交换到它的children都小于它的key值为止,这个过程最多进行这个tree的高度次(即:the height of tree), 而这个height就是O(logN)。我们称这个过程为Max-Heapify或者Min-Heapify。以下展示的是C++的代码来实现Max-heapify的过程, 如下:
/*
heapify() function is used to keep the heap structure as max/min heap. If there is a node voilate the max/min heap, this function will try to correct it and restructure it still keep the max/min heap property. parameter: 1. a[], the array
2. i; where the node violate the max/min heap
3. n; the numbers of the a[]; return: void */
void heapify(int a[], int i, int n){ int j, temp;
j = *i;//the node i's left node if (j >= n){//i is the leaf of the tree return;
} temp = a[i]; while (j < n) {//i is not the leaf if (a[j]<a[j+]) {//left child is less than right child j = j + ;
} if (temp>a[j]) { break;
} if (temp <= a[j]) {// if node i violate the structure, exchange the values. a[j/] = a[j];
a[j] = temp;
j = j * ;
} }
}
以上的代码展示的是max-heapify 的过程, 那么如何将一个乱续的heap或者array重构成一个max-heap或者min-heap呢?其实有了以上的功能,将一个完全杂乱的heap装换成max-heap就很简单了。我们只需要从倒数第二层的最左边的一个element开始一直向上面的level的nodes做Max-heapify的过程utill to the root of the tree, 最后就一定能将整个heap转化成Max-Heap. 倒数第二层的最左边的一个element的index是N/2 - 1; 这中间的整个过程如下所示:

将整个unsorted heap转化成Max-Heap的过程的时间复杂度Efficiency = O(N), 而不是O(LogN); 这个复杂度的推导过程下次再跟大家解释,是通过数学运算推导出来的,这里就不详细解释了。其实这个代码很简单,他的C++的实现代码如下:
/* buildMaxHeap functions is used to force and restructure the heap to an maximum heap structure
parameters: 1: a[];
2: n;// the number of the arrary return void
*/ void buildMaxHeap(int a[], int n){ for (int i = n/-; i >= ; i --) { heapify(a, i, n);
} }
进过以上的过程,我们知道了如何将一个无序的heap或者array转换成Max-Heap, 那么接下来我们就解释一下如何将获得的Max-heap进行排序,它主要经过一下几个过程:
1. 交换heap的最后一个key a[N]和heap的root的key a[1]; 此时a[1]破坏了Max-heap的structure,a[N]是最大值。
2. 我们对除了最后几个已经交换过值的elements剩下的tree进行heapfy的过程;//假如从[j.....N]的elements是之前比较过的,那么就只对[1......j-1]进行heapify的过程。
其具体的c++代码的实现过程如下所示:
/*
heapSort function is to sort the heap in an descending or ascending order parameter:
1, a[], //the array
2, n,// how many nodes should be checked in the heapify function, actuall here is not all the node should be checked return void */ void heapSort(int a[], int n){ int temp; for (int i = n-; i >= ; i --) {//the last indices of array is n-1, loop until to the root temp = a[];
a[] = a[i];
a[i] = temp; heapify(a, , i-);
}
}
综合以上的不做,我们已经可以完成对一个完全无序的array或者heap进行heap-sort的过程,它的时间复杂度如下:
Efficiency = O(N)+O(1)+O(N*logN) = O(N*logN);
那么heap的总结就结束了,下周准备写一些Binary Search Tree (BST)的知识。
如果有什么错误的地方,欢迎大家留言指正,谢谢。
Heap Sorting 总结 (C++)的更多相关文章
- Heap & Priority Queue
Heap & Priority Queue Definition & Description: In computer science/data structures, a prior ...
- Find K most Frequent items in array
给定一个String数组,求K个出现最频繁的数. 记录一下查到的资料和思路: 1. 使用heap sorting, 先用hashmap求出单词和词频.需要额外建立一个class Node,把单词和词频 ...
- 常见排序算法及其java实现
最近学习了下java,感觉java在基本语法上与C++非常相似.作为练习,我用java实现了冒泡排序.选择排序.插入排序.基尔排序.快速排序.堆排序.计数排序.合并排序. 以下为实现代码: publi ...
- java学习笔记(详细)
java平台 1.J2SE java开发平台标准版 2.J2EE java开发平台企业版 java程序需要在虚拟机上才可以运行,换言之只要有虚拟机的系统都可以运行java程序.不同系统上要安装对应的虚 ...
- 算法分析中最常用的几种排序算法(插入排序、希尔排序、冒泡排序、选择排序、快速排序,归并排序)C 语言版
每次开始动手写算法,都是先把插入排序,冒泡排序写一遍,十次有九次是重复的,所以这次下定决心,将所有常规的排序算法写了一遍,以便日后熟悉. 以下代码总用一个main函数和一个自定义的CommonFunc ...
- Insert or Merge && Insertion or Heap Sort
原题连接:https://pta.patest.cn/pta/test/1342/exam/4/question/27102 题目如下: According to Wikipedia: Inserti ...
- PTA Insertion or Heap Sort
According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...
- 1306. Sorting Algorithm 2016 12 30
1306. Sorting Algorithm Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description One of the f ...
- 09-排序3 Insertion or Heap Sort
和前一题差不多,把归并排序换成了堆排序.要点还是每一次排序进行判断 开始犯了个错误 堆排序该用origin2 结果一直在排序origin ,误导了半天以为是逻辑错误...一直在检查逻辑 建立最大堆 排 ...
随机推荐
- 工信部:我国4G用户近9.5亿 用户平均使用流量近2G
刚刚沿着广场转了一圈,我竟发现自己离他只有几步之遥,又在那条人行道上,刚才催促我前进的自豪感突然之间被惊慌代替.陌生人看着我,脸上流露出一种遗憾的表情,他向我靠近,轻轻摇着脑袋,像是为某个不受人控制的 ...
- Java跨域问题的处理详解
1,JavaScript由于安全性方面的考虑,不允许页面跨域调用其他页面的对象,那么问题来了,什么是跨域问题? 答:这是由于浏览器同源策略的限制,现在所有支持JavaScript的浏览器都使用了这个策 ...
- SPARK 创建新任务
1.应用程序创建 SparkContext 的实例 sc 2.利用 SparkContext 的实例来创建生成 RDD 3.经过一连串的 transformation 操作,原始的 RDD 转换成为其 ...
- intelliJ IDEA安装、激活与汉化
1.去intelliJ IDEA 官网下载idea,选择Ultimate版本(非免费版,community免费但功能较少) 2.开始安装 3.选择好路径 4.选择在桌面创建的快捷方式(注意32bit和 ...
- 树莓派.使用Node.js控制GPIO
树莓派上的40个GPIO是最好玩的东西 它们可以被C,/C++, Python, Java等语言直接控制 现在就来看看怎么用Node.js做到同样的事情 在试验之前, 请先安装好Node.js, 具体 ...
- poi入门之读写excel
Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.该篇是介绍poi基本的 ...
- C#中的异常处理(try-catch的使用)——使程序更加稳定
使用try-catch来对代码中容易出现异常的语句进行异常捕获. try { 可能出现异常的代码: } catch { 出现异常后需要执行的代码: } 注:1.在执行过程中,如果try中的代码没有出现 ...
- angular核心$watch,$digest,$apply之间的联系
浏览器事件发生时,会在浏览器的上下文window中执行,而angular有自己的上下文angular content,angular 事件在自己的上下文angular content中执行. $wat ...
- 老大哥在看着你!我国部署超2000万个AI监控系统
原文:Big brother is watching you! China installs 'the world's most advanced video surveillance system' ...
- Ionic3 打包并签名Android-App
ionic cordova build android --prod --release 此时,在项目根目录中看下看到生成的apk文件:platforms\android\build\outputs\ ...