各位读者,大家好。 因为算法和数据结构相关的知识都是在国外学的,所以有些词汇翻译的可能不准确,然后一些源代码的注释可能是英文的,如有给大家带来什么不方便,请见谅。今天我想写一下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++)的更多相关文章

  1. Heap &amp; Priority Queue

    Heap & Priority Queue Definition & Description: In computer science/data structures, a prior ...

  2. Find K most Frequent items in array

    给定一个String数组,求K个出现最频繁的数. 记录一下查到的资料和思路: 1. 使用heap sorting, 先用hashmap求出单词和词频.需要额外建立一个class Node,把单词和词频 ...

  3. 常见排序算法及其java实现

    最近学习了下java,感觉java在基本语法上与C++非常相似.作为练习,我用java实现了冒泡排序.选择排序.插入排序.基尔排序.快速排序.堆排序.计数排序.合并排序. 以下为实现代码: publi ...

  4. java学习笔记(详细)

    java平台 1.J2SE java开发平台标准版 2.J2EE java开发平台企业版 java程序需要在虚拟机上才可以运行,换言之只要有虚拟机的系统都可以运行java程序.不同系统上要安装对应的虚 ...

  5. 算法分析中最常用的几种排序算法(插入排序、希尔排序、冒泡排序、选择排序、快速排序,归并排序)C 语言版

    每次开始动手写算法,都是先把插入排序,冒泡排序写一遍,十次有九次是重复的,所以这次下定决心,将所有常规的排序算法写了一遍,以便日后熟悉. 以下代码总用一个main函数和一个自定义的CommonFunc ...

  6. Insert or Merge && Insertion or Heap Sort

    原题连接:https://pta.patest.cn/pta/test/1342/exam/4/question/27102 题目如下: According to Wikipedia: Inserti ...

  7. PTA Insertion or Heap Sort

    According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...

  8. 1306. Sorting Algorithm 2016 12 30

    1306. Sorting Algorithm Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description One of the f ...

  9. 09-排序3 Insertion or Heap Sort

    和前一题差不多,把归并排序换成了堆排序.要点还是每一次排序进行判断 开始犯了个错误 堆排序该用origin2 结果一直在排序origin ,误导了半天以为是逻辑错误...一直在检查逻辑 建立最大堆 排 ...

随机推荐

  1. putty 的美化

    1.       中文乱码问题. 这个问题由来已久,每当我查看 mount到linux下的windows 中文目录的时候,都是一堆乱码, putty 也拒绝我输入中文, 一句话,这玩意,对中文过敏. ...

  2. 基于FFMpeg的C#录屏全攻略

    最近负责一个录屏的小项目,需要录制Windows窗口内容并压缩保存到指定文件夹,本想使用已有的录屏软件,但是本着学习的态度去探索了FFMpeg,本文主要介绍基于FFMpeg开源项目的C#录屏软件开发. ...

  3. Git相关操作一

    1.将目录变为Git项目: 输入git init将当期目录变为Git项目 git init git项目可以被认为分为三个区域,Working Directory,Staging Area,Reposi ...

  4. 【ASP.NET MVC 学习笔记】- 16 Model Binding(模型绑定)

    本文参考:http://www.cnblogs.com/willick/p/3424188.html. 1.Model Binding是Http请求和Action方法之间的桥梁,是MVC框架根据Htt ...

  5. abapGit简介与教程

    你是ABAP开发者?你用abapGit吗? 看到这个问题,读者也许会想,什么是abapGit?就让我们从这个问题开始.简单地说,abapGit是一个以ABAP写成为ABAP服务的Git客户端. 有的读 ...

  6. component及刚体rigidbody用法

    关于getcomponent函数,rigidbody(2d)的嵌套关系及用法 1.getcomponent函数 在unity中脚本可以看成是可定义的组件,我们经常要访问同一对象或不同对象中的脚本,可以 ...

  7. OpenCV Image Watch 调试插件

    昨晚偶然发现vs2012的这个很神奇的插件,对于经常使用opencv的人来说,这个插件无疑是我们的调试神器.今天马上下载试用,感觉超级棒!~以后要想查看图像结果,不用再imshow了! Image W ...

  8. Leetcode题解(五)

    17.Letter Combinations of a Phone Number 题目 针对输入的数字串,每一个数字都对应对个字符可以选择.因此可以直接采用递归的思想,依次遍历数字串的每一个数字,处理 ...

  9. javascript中new操作符

    当代码var p= new Person("tom")执行时,其实内部做了如下几件事情: 1.创建一个空白对象(new Object()). 2.拷贝Person.prototyp ...

  10. css 3d

    Perspective  透视点,视角,CSS3D 的透视点在浏览器前方 默认值为none,是作用于子元素,指定观察者与z=0平面的距离,使具有三维位置变换的元素产生透视效果.z>0的三维元素比 ...