数据结构学习记录——堆的建立(最大堆的建立、思路图解、代码实现、代码解释)

简介: 数据结构学习记录——堆的建立(最大堆的建立、思路图解、代码实现、代码解释)

最大堆的建立

建立最大堆:将已经存在的N个元素按最大堆的要求存放在一个一维数组中。

方法1

通过插入操作,将N个元素一个一个地插入到一个初始为空的堆中去。堆插入的时间复杂度为log2N2,插人N个元素,那么最终建立堆的时间复杂度就为O(Nlog2N)(2)

方法2

线性时间复杂度下建立最大堆。

(1)将N个元素按输入顺序存入,先满足完全二叉树的结构特性

(2)调整各结点位置,以满足最大堆的有序性

我们当然要选择更高效率的方法,下面就来看看方法2具体是怎样实现的:

思路图解

假设现在有12个元素,已经按输入顺序存入,满足了完全二叉树的结构特性:

对其进行调整,调整的思路和堆的删除相似,但是要从后往前开始,在左右两个堆中进行调整;我们从倒数第一个有儿子的结点开始调整。因为倒数第一个结点一定是只有左儿子或者有一个左儿子和一个右儿子,即左右两边一定是堆的结构

调整完倒数第一个有儿子 的结点之后,往上再进行调整。

重复操作

继续往上,到上一层了。  

循环


最终调整完成 :

代码实现

/* 下滤操作:将H中以H->Data[p]为根的子堆调整为最大堆 */
void PercDown( MaxHeap H, int p )
{ 
    int Parent, Child;
    ElementType X;
 
    X = H->Data[p]; /* 取出根结点存放的值 */
    for( Parent=p; Parent*2<=H->Size; Parent=Child )
    {
        Child = Parent * 2;
        if( (Child!=H->Size) && (H->Data[Child]<H->Data[Child+1]) )
        {
            Child++;  /* Child指向左右子结点的较大者 */
        }
        if( X >= H->Data[Child] ) 
        {
            break; /* 找到了合适位置 */
        }
        else
        {
            /* 下滤X */
            H->Data[Parent] = H->Data[Child];
        } 
    }
    H->Data[Parent] = X;
}
 
/* 将一个无序的数组调整为最大堆  */
void BuildHeap( MaxHeap H )
{ 
  /* 这里假设所有H->Size个元素已经存在H->Data[]中 */
 
    int i;
 
    /* 从最后一个结点的父节点开始,到根结点1 */
    for( i = H->Size/2; i>0; i-- )
        PercDown( H, i );
}

代码解释

PercDown

PercDown函数用于将以某个结点为根的子树调整为最大堆。

其中,参数p,表示要下滤的结点在H中的下标。

Parent表示当前结点的父结点,Child表示当前结点的子结点,X表示当前结点的值。

首先,将要下滤的结点的值X取出来,保存在一个临时变量中。

然后,从要下滤的结点开始,沿着其左右子结点中较大的一个不断下滤,


直到找到X的合适位置或者到达叶结点为止。(Child的判断那里与堆的删除那里是一致的)


具体来说,每次将要下滤的结点与其左右子结点中较大的一个进行比较,


如果X比较大,则说明X已经找到了合适的位置,可以退出循环;(最大堆根结点比左右子结点都要大)

否则,将较大的子节点上移一层,继续下滤。

最后,将X放到找到的合适位置上,完成下滤操作。

BuildHeap

BuildHeap函数用于将一个无序的数组调整为最大堆。

从倒数第一个没有儿子的结点开始,即从最后一个非叶子节点开始,依次进行下滤操作,将其子树调整为最大堆。

因为最后一个非叶子节点的数组下标为n/2,其中n为堆中元素的个数,所以从i=n/2开始循环。

循环执行,直到整个数组都被调整为最大堆。

综上,BuildHeap函数的时间复杂度为O(N),其中N为堆中元素的个数。因为每个结点最多只需要下滤一次,而下滤的时间复杂度为O(log2N),所以建立一个最大堆,总的时间复杂度为O(Nlog2N)。与开头所说相符合,效率较方法1要更高。



end



目录
相关文章
|
14天前
|
存储 算法 Java
散列表的数据结构以及对象在JVM堆中的存储过程
本文介绍了散列表的基本概念及其在JVM中的应用,详细讲解了散列表的结构、对象存储过程、Hashtable的扩容机制及与HashMap的区别。通过实例和图解,帮助读者理解散列表的工作原理和优化策略。
29 1
散列表的数据结构以及对象在JVM堆中的存储过程
|
1月前
|
存储 算法
数据结构与算法学习二二:图的学习、图的概念、图的深度和广度优先遍历
这篇文章详细介绍了图的概念、表示方式以及深度优先遍历和广度优先遍历的算法实现。
52 1
数据结构与算法学习二二:图的学习、图的概念、图的深度和广度优先遍历
|
19天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
16天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
58 16
|
19天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
20天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
19天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
20天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
19天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
20天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明