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 ,误导了半天以为是逻辑错误...一直在检查逻辑 建立最大堆 排 ...
随机推荐
- ~.NET下国际化i18n简单示例
因业务需要,后台站点需要出一个国际化的解决方案,偷懒后用微软自带资源文件暂时解决.废话不多说,进入正题. 第一步:在项目菜单下选择添加国际化资源文件夹. 第二部:添加完毕之后,添加各语言版本下的资源信 ...
- java字串加密
字串加密 1.设计思想: (1)加密方法,字符串的每一个字符都代表这个字符往后的第三位,最后三个字符代表,开始的三个字符. (2)解密方法,字符串的每一个字符都代表这个字符往前的第三位,开始三个字符代 ...
- 高性能 Java 缓存库 — Caffeine
http://www.baeldung.com/java-caching-caffeine 作者:baeldung 译者:oopsguy.com 1.介绍 在本文中,我们来看看 Caffeine - ...
- JAVA中HashMap和Hashtable区别
Hashtable和HashMap在Java面试中相当容易被问到,甚至成为了集合框架面试题中最常被考的问题,所以在参加任何Java面试之前,都不要忘了准备这一题. 我们先看2个类的定义 public ...
- [ACdream]瑶瑶带你玩激光坦克
题目链接:http://acdream.info/contest?cid=1269#problem-B Problem Description 有一款名为激光坦克的游戏,游戏规则是用一个坦克发出激光来 ...
- [http服务]
[http服务] CentOS 6 httpd 程序环境 记录了httpd的主进程编号: v 主程序文件: /usr/sbin/httpd /usr/sbin/httpd.worker /usr/sb ...
- 写出易于调试的SQL
1.前言 相比高级语言的调试如C# , 调试SQL是件痛苦的事 . 特别是那些上千行的存储过程, 更是我等码农的噩梦. 在将上千行存储过程的SQL 分解到 C# 管理后, 也存在调试的不通畅, 如何让 ...
- Prime Ring Problem
Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ... ...
- 记录下 Markdown 语法
github上常用markdown语法:Mastering Markdown 目录 0. 目录 1. 锚点 2.标题 3.超链接 3.1.行内式 3.2.自动链接 4.列表 4.1.有序列表 4.2. ...
- [Redis源码阅读]sds字符串实现
初衷 从开始工作就开始使用Redis,也有一段时间了,但都只是停留在使用阶段,没有往更深的角度探索,每次想读源码都止步在阅读书籍上,因为看完书很快又忘了,这次逼自己先读代码.因为个人觉得写作需要阅读文 ...