算法导论第四版ch6堆排序中文笔记与最大堆的c++实现

算法导论第四版ch6中文笔记与最大堆的c++实现

作者:Claude Du
本文文字内容和图片基本来源于算法导论第四版第6章。
堆排序的时间复杂度与并归排序一样, 空间复杂度与插入排序同样有空间原址性。堆排序是集合了并归排序与插入排序两者优点的一种排序算法,其使用了称为“堆”的数据结构,该数据结构不仅可以用于堆排序,还可以构造有效的优先队列。

6.1 堆

堆:堆是一个数组,可以看成一个近似的完全二叉树

一个节点的父节点,左孩子和右孩子的相应下标,对应关系如下代码所示,相应图示如图6.1:
在这里插入图片描述

// the index of this MaxHeap follows the convention of the Introduction to Algorithm Chap6
// which means the root of a maxHeap is maxHeap[0] instead of maxHeap[1],
// and the last element of a maxHeap is  maxHeap[heapSize] instead of maxHeap[heapSize - 1]
inline size_t PARENT(size_t x) {
   
    return x / 2;
}
inline size_t LEFT(size_t x) {
   
    return x * 2;
}
inline size_t RIGHT(size_t x) {
   
    return x * 2 + 1;
}

最大堆的性质: A [ P A R E N T ( i ) ] ≥ A [ i ] A[PARENT(i)] \geq A[i] A[PARENT(i)]A[i]

最小堆的性质: A [ P A R E N T ( i ) ] ≤ A [ i ] A[PARENT(i)] \leq A[i] A[PARENT(i)]A[i]

如果把堆看成一棵树,那么堆中某一节点的高度:该节点到叶结点的最长简单路径上边的数目。堆上的一些基本操作的运行时间基本和树的高度成正比。

接下来要介绍的是堆上的一些核心基本操作过程,并说明如何在排序算法和优先队列中应用它们:

6.2 维护最大堆的性质

6.3 构造最大堆

6.4 堆排序

6.5 利用堆实现优先队列

6.2 维护最大堆的性质

MaxHeapify是用于维护最大堆性质的重要过程。在任何时候调用MaxHeapify时,我们假定根节点为LEFT(i) 和RIGHT(i)的二叉树都是最大堆。

MaxHeapify 通过不断让vec_[i]在堆中“逐层下降”,从而使得以下标i为根节点的子树再次遵循最大堆的性质。

MAX-HEAPIFY c++代码实现如下:

template <typename T> class MaxHeap {
   
private:
    vector<T> vec_;
    size_t heapSize = 0;
    size_t size = 0;
    // recursion version of MaxHeapify, personally don't like it
    void MaxHeapify(size_t i) {
   
        size_t left = LEFT(i);
        size_t right = RIGHT(i);
        size_t largest = i;
        if (left <= heapSize && vec_[left] > vec_[largest]) largest = left;
        if (right <= heapSize && vec_[right] > vec_[largest]) largest = right;
        if (largest == i) return;
        // exchange vec_[i] with vec_[largest]
        T temp = vec_[i];
        vec_[i] = vec_[largest];
        vec_[largest] = temp;
        MaxHeapify(largest);
    }
    void BuildMaxHeap();
public: 
    MaxHeap(vector<T> vec): vec_(vec){
   
        if (vec.size() < 1) std::cerr << "the size of Heap is smaller than one" << st
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值