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

    本人为小白,首次写博客  有不正确的地方望多多指点与见谅!! 一,改变HTML的内容 语法: document.getElementById(id).innerHTML=new HTML: 具体用法: ...

  2. 设置vim的默认工作路径同时与自动设当前编辑的文件所在目录为当前工作路径不冲突

    问题: 想让vim自动设当前编辑的文件所在目录为当前工作路径不冲突,但是当vim新建文件的时候,工作路径会又自动切换缓存path下. 如何使当使用vim打开文件时,vim的工作路径是当前文件所在的路径 ...

  3. 相对定位的div没有出现纵向滚动条

    在一个相对定位的div中绝对定位很多html元素,纵向没有滚动条出现.原因:我们期望作为原点的点在窗口原点的下方,但是滚动条以窗口原点作为原点,所以没有出现滚动条.解决:在div外面再套一个div,o ...

  4. CentOS设置系统时间、硬件时间、以及定时校对时间

    CentOS设置系统时间和时区 一.设置时区 方法一:使用setup工具 setup 选择Timezone configuration 选择Asia/Shanghai 空格键勾选上System clo ...

  5. Java基础笔记5

    方法(函数) 就是一块可以重复调用的代码块. 比如.100行代码. 在多处使用. 方法的格式 public static 返回类型 方法名称(参数列表){ } 返回类型:当方法被调用时,把返回内容 交 ...

  6. (转)Spark JAVA RDD API

    对API的解释: 1.1 transform l  map(func):对调用map的RDD数据集中的每个element都使用func,然后返回一个新的RDD,这个返回的数据集是分布式的数据集 l   ...

  7. Leetcode题解(21)

    62. Unique Paths 题目 分析: 机器人一共要走m+n-2步,现在举个例子类比,有一个m+n-2位的二进制数,现在要在其中的m位填0,其余各位填1,一共有C(m+n-2,m-1)种可能, ...

  8. 2015ACM/ICPC亚洲区沈阳站 B-Bazinga

    Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  9. Android 开发笔记___textvieww__跑马灯效果

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  10. html5客户端本地存储之sessionStorage及storage事件

    首先您可以看一下<JavaScript本地存储实践(html5的localStorage和ie的userData)>sessionStorage和上文中提到的localStorage非常相 ...