《算法导论》

摘要:
=i){swap;i=largest;left=Left;right=Right;iflargest=left;elselargest=i;iflargest=right;}}6.2-6对于一个大小为n个堆,MaxHeapify函数每处理一次结点高度+1,最坏情况下,函数处理从根节点至最大叶节点,为整个树的高度logn,因此函数最坏运行时间也为6.3建堆6.3-2[待补充]6.3-3参考6.4堆排序算法6.4-2堆排序算法HeapSort输入是一个大顶堆,输出是一个递增有序序列,由图6-4所示每次执行完该算法的2~5行迭代时,子数组A[1i]中即是已排好序的i个元素,而此时A[i+1n]中是其余ni个元素构成的大顶堆,也是数组A中ni个最大元素。

GitHub 见solution.txt

6.1 堆

6.1-1

在高度为h的堆中,最多元素为2(h+1)1个,最少元素有 2h+1

6.1-3

最大堆的特性是除了根结点外的每个结点都有A[PARENT(i)]>=A[i]故,在一个最大堆的某颗子树中最大元素必然位于该子树的根上。

6.1-4

根据最大堆的性质,任何子树的子结点都小于根节点,故整棵树的最小元素必然位于堆的最底层或者倒数第二层的叶子结点。

6.1-5

不一定,是最小堆也可能是最大堆

6.1-6

不是,画出相应堆结构发现元素7是元素6的右孩子,7>6,不满足最大堆性质。

6.1-7

证明,当用数组表示存储了n个元素的堆时,
除根节点,满足

PARENT(i)
    return i/2

除叶子结点,满足

LEFT(i)
    return 2*i
RIGHT(i)
    return 2*i+1

堆中,最大根节点的下标为 floor(n/2) ,因此数组中下标在 n/2 后的元素
将都是堆中的叶子结点。

6.2 保持堆的性质6.2-2

C++代码如下:

void minHeapify(int *data, int i)
{
    int minPos;
    int left = Left(i);
    int right = Right(i);

    if (left <= m_heapSize && data[left-1] < data[i-1])
        minPos = left;
    else
        minPos = i;

    if (right <= m_heapSize && data[right-1] < data[minPos-1])
        minPos = right;

    if (minPos != i)
    {
        swap(data[i - 1], data[minPos - 1]);
        minHeapify(data, minPos);
    }
}

6.2-3

直接返回

6.2-4

此时i结点没有左右孩子,函数直接返回

6.2-5

迭代实现的manHeapify

void MaxHeap::maxHeapify(int *data, int i)
{
    int largest;

    int left = Left(i);
    int right = Right(i);

    if (left <= m_heapSize && data[left-1] > data[i-1])
        largest = left;
    else
        largest = i;

    if (right <= m_heapSize && data[right-1] > data[largest-1])
        largest = right;

    while(largest != i)
    {
        swap(data[i - 1], data[largest - 1]);
        i = largest;
        left = Left(i);
        right = Right(i);

        if (left <= m_heapSize && data[left-1] > data[i-1])
            largest = left;
        else
            largest = i;
        if (right <= m_heapSize && data[right-1] > data[largest-1])
            largest = right;
    }
}

6.2-6

对于一个大小为n个堆,MaxHeapify函数每处理一次结点高度+1,最坏情况下,函数处理从根节点至最大叶节点,为整个树的高度logn,因此函数最坏运行时间也为(logn)

6.3 建堆

6.3-2

[待补充]

6.3-3

参考

6.4 堆排序算法

6.4-2

堆排序算法HeapSort输入是一个大顶堆,输出是一个递增有序序列,由图6-4所示每次执行完该算法的2~5行迭代时,子数组A[1i]中即是已排好序的i个元素,而此时A[i+1n]中是其余ni个元素构成的大顶堆,也是数组A中ni个最大元素。

6.4-3

对于n个递增数组A,堆排序T(n)=o(nlogn)
对于n个递减数组A,堆排序T(n)=o(n)

6.4-4

堆排序算法中,对A中每个元素最多处理一次:
(1)取下头结点,O(1)
(2)把最后一个结点移到根结点位置,O(1)
(3)对该结点执行MAX-HEAPIFY,最坏时间为O(lgn)
对每个结点处理的最坏时间是O(lgn),每个结点最多处理一次。
因此堆排序的最坏情况运行时间为floor(nlogn)

6.5 优先级队列

未完待续 ^||^ ~~~

思考题

未完待续 ^||^ ~~~

免责声明:文章转载自《《算法导论》》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇shell获取帮助第二点五个不高兴的小明下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

对B+树,B树,红黑树的理解

 出处:https://www.jianshu.com/p/86a1fd2d7406 写在前面,好像不同的教材对b树,b-树的定义不一样。我就不纠结这个到底是叫b-树还是b-树了。 如图所示,区别有以下两点: B+树中只有叶子节点会带有指向记录的指针,而B树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点中。 B+树中所有叶子节点都是通...

gzip压缩算法

gzip,zlib,以及图形格式png,使用的是同一个压缩算法deflate。我们通过对gzip源码的分析来对deflate压缩算法做一个详细的说明: 第一,gzip压缩算法基本原理的说明。 第二,gzip压缩算法实现方法的说明。 第三,gzip实现源码级的说明。 1. Gzip压缩算法的原理          gzip 对于要压缩的文件,首先使用LZ7...

Aho

Aho - Corasick string matching algorithm 俗称:多模式匹配算法,它是对 Knuth - Morris - pratt algorithm (单模式匹配算法) 形成多模式匹配算法的一种改进,如果我们用单模式匹配算法实现多模式匹配算法,假如模式串有 M 个 , 则需要重复调用 M 次单模式匹配算法 ; 举个很简单的例子,...

堆排序算法实现

关于堆排序算法的思想,网上有很多介绍,这里不再解释,这里提供了两个Java类,读者可以把类潜入到自己的程序中,直接调用,免去了重新编写堆排序的过程。 分为两个堆排序接口,一个是数组从下标1开始存储的堆排序类Duisort1,另一个是从下标0开始存储的堆排序类Duisort2,具体的Java代码如下: 1 import java.util.*;...

redis的zset结构跳表

一、数据结构与算法——跳表 什么是跳表 跳表全称为跳跃列表,它允许快速查询,插入和删除一个有序连续元素的数据链表。跳跃列表的平均查找和插入时间复杂度都是O(logn)。快速查询是通过维护一个多层次的链表,且每一层链表中的元素是前一层链表元素的子集(见右边的示意图)。一开始时,算法在最稀疏的层次进行搜索,直至需要查找的元素在该层两个相邻的元素中间。这时,算法...

ZooKeeper学习及其C++ client

目录 概念 ZAB协议(ZooKeeper Atomic Broadcast)简介 ZooKeeper使用场景 服务发现 分布式锁 分布式leader选举 ZooKeeper client API (原生API) ZooKeeper client API (高级API) cpp zookeeper client项目 参考 概念 ZooKeep...