算法导论第六章之最大、最小堆

原创 2017年04月08日 00:24:53

堆是很重要的一种数据结构,常常用在排序和优先队列的实现上,当然在C++ STL中有优先队列的实现,但是者并不妨碍我们去学习他。

堆其实是一种数组对象,也就是说他的数据全部都存储在数组中,它可以被视为一棵完全二叉树(不懂二叉树的请自行百度)。(二叉堆)堆有两种:最大堆和最小堆。

最大堆
通俗来讲,满足下面要求的完全二叉树为最大堆:
除了根节点以外的每一个节点i,有:
A[Parent]>=A[i]
注:数组A[]是存储堆元素的数组。
这样堆中的最大值明显是存储在根节点中的(如果有和根节点同样大的值,其子节点也会存储最大的数据)。

最小堆:
最小堆和最大堆有点相反的意思,其满足的条件是在完全二叉树中,除了根节点以外的节点i,有:
A[Parent]<=a[i]

主要的运用的基本过程:
下面以最大堆来描述各个过程和实现

MAX-HEAPIFY()过程:
保持最大堆的性质,那么我们假设某个节点i,他的左子树LEFT(i)和右子数都是最大堆,那么节点i对于他的两棵子树来说可能会小于子数节点,这时候就需要对堆进行调整。运行时间O(lgn);

实现代码:
**

//这里和书上不太一样,因为他的伪代码直接有heapSize
MAX—HEAPIFY(a,int i,int heapSize){
int largest;
int change;
int l = a[i/2];
int r = a[i/2+1];
if(l<=heapSize&&a[l]>a[i])
    largest = l;
if(r<=heapSize&&a[r]>a[l])
    largest = r;
if(largest!=i){
    change = a[i];
    a[i] = a[largest];
    a[largest] = change;
    MAX-HEAPFIPY(A,largest,heapSize);
}
}
注:只有节点i和其子节点有过交换才会继续判断,否则就是满足最大堆的要求的。

BUILD-MAX-HEAP()过程:
对于一个存储数组(存储着堆 的节点的值),我们知道1…..n个节点的时候从n/2+1到n是叶子节点,那么一个叶子节点肯定是一个堆,所以我们对堆进行处理一般是对非叶子结点进行处理。代码如下:

BUILD—MAX-HEAP(A,int heapSize){
    for(int i = heapSize/2+1;i<n;i++)
         MAX-HEAPIFY(A,i,heapSize);
}

HEAPSORT()过程:
HEAP()就是堆排序过程,首先将给定的数据排列成一个最大,最小堆(这里以最大堆为例),然后在对堆进行排序:

HEAPSORT(A,int heapSize){
   BUILD—MAX-HEAP(A,heapsize);
    int leap;
    for(int i = heapSsize-1;i>0;i--){
        leap = a[0];
        a[0] = a[i];
        a[i] = leap;
        heapSize -= 1;
        BUILD-MAX-HEAP(A,a[0],heapSize);  
     }
  }

最小堆的运用实现:

最小堆其实很像最大堆的一个相反的过程。

MIN-HEAPIFY()过程:

MIN—HEAPIFY(a,int i,int heapSize){
int smallest;
int change;
int l = a[i/2];
int r = a[i/2+1];
if(l<=heapSize&&a[l]<a[i])
    largest = l;
if(r<=heapSize&&a[r]<a[l])
    smallest = r;
if(smallest!=i){
    change = a[i];
    a[i] = a[smallest];
    a[smallest] = change;
    MAX-HEAPFIPY(A,smallest,heapSize);
}
}

BUILD—MIN-HEAP过程

BUILD—MIN-HEAP(A,int heapSize){
    for(int i = heapSize/2+1;i<n;i++)
         MIn-HEAPIFY(A,i,heapSize);
}

HEAPSORT()过程

HEAPSORT(A,int heapSize){
    BUILD—MIN-HEAP(A,heapsize);
    int b[N];  ///因为我们的a[0]就是最小,如果想要填补我们有另外一个                                          // 数组            
    int leap;
    int k = 0;
    for(int i = heapSsize-1;i>0;i--){
        b[k++] = a[0];
        a[0] = a[i];
        heapSize -= 1;
        BUILD-MIN-HEAP(A,a[0],heapSize);  
     }
     b[k++] = a[0];
     for(int i=0;i<k;i++)
        a[i] = b[i];
  }

相关文章推荐

算法导论6.5-8习题解答(最小堆K路合并)

《算法导论》第六章第五节的第8题,原题为:请给出一个时间为O(nlgk)、用来将k个已排序链表合并为一个排序链表的算法。此处n为所有输入链表中元素的总数。(提示:用一个最小堆来做k路合并)。 算...

“用最小堆将k个已排序链表合并为一个排序链表”(算法导论 练习6.5-9)

问题:请给出一个时间为O(nlgk),用来将k个已排序链表合并为一个排序链表的算法。此处的n为所有输入链表中元素的总数。(提示:用一个最小堆来做k路合并) 编程思路: 假设k个链表都是非降...

堆排序(最小堆)--【算法导论】

堆排序的思想在堆排序(最大堆)已做说明,故不再赘述; 总之,思想就是首先进行建堆,由于这是最小堆,故而必须保证父节点都小于孩子节点,若不满足条件,则进行调节; 最后进行堆排序,不断将最小的提取出来...
  • xjm199
  • xjm199
  • 2014年01月08日 21:39
  • 3678

算法兴趣----- 一亿数据获取前100个最大值(仅供参考,基于快速排序的实现时间不稳定,基于最小堆实现。如果我们只要求前K个最大(小)值的时候,用堆是最好的选择,因为这里不用每次都排序了)

文章来源:http://blog.csdn.net/beiyeqingteng/article/details/7534489 前言: 刚刚在CSDN上看到一个网友利用最小堆实现 “ 获取一亿数...

贪心算法之最小堆实现霍夫曼编码

贪心算法之最小堆实现霍夫曼编码 实现之前需要学习的地方: 如果你不了解堆、堆的插入、堆的删除,可以先看下我前面几篇博客 http://blog.csdn.net/u011068702/artic...

【算法导论】第六章 再谈 堆排序和最大优先级队列

摘自书本: 这一部分将要给出几个解决以下排序问题的算法: 输入:n 个数的序列( a1,a2,……,an )。 输出:输入序列的一个重排 (a1’,a2’,……,an’ ),使 a1’ ...

算法导论学习:分治策略之最大子数组问题

对于分治策略,是算法中很重要的一个环节,它能够将一个很大的问题分解为一个个的小问题,从而降低求解难度。今天,我就对《算法导论》中的最大字数组问题进行分析,并给出书中伪代码的C/C++语言表现形式,同时...

算法导论学习笔记(二)分治策略之最大子数组

算法导论学习笔记(二)分治策略之最大子数组
  • zjphqpz
  • zjphqpz
  • 2016年04月30日 22:03
  • 157

分治之最大子数组-《算法导论》学习笔记四

《算法导论》第4章4.1使用分治策略求最大子数组(数组包含负数,不然整个数组即使最大子数组,求解没意义)。思路:数组头为low,尾为high,mid=(low+high)/2,这样将数组分为了两段。首...

算法导论之最大子数组问题

//寻找最大子数组,使该子数组元素之和为所有子数组中最大的 /* * 算法: * 1。利用分治策略,逐层寻找 * 2.最大子数组存在三种情况:若将数组在中间元素位置划分为两部分,则最大子...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:算法导论第六章之最大、最小堆
举报原因:
原因补充:

(最多只允许输入30个字)