中华鲁迅的专栏

鲁迅的性格,鲁迅一般的人品。

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

堆是很重要的一种数据结构,常常用在排序和优先队列的实现上,当然在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];
  }
阅读更多
文章标签: 算法导论
想对作者说点什么? 我来说一句

算法导论第六章习题解答

2015年08月19日 10KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭