数据结构之堆详解

2025-05-27 0 76

1. 概述

(也叫优先队列),是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶和小顶)。它常用于管理算法执行过程中的信息,应用场景包括排序,优先队列等。

2. 的基本操作

是一棵完全二叉树,高度为O(lg n),其基本操作至多与树的高度成正比。在介绍的基本操作之前,先介绍几个基本术语:

A:用于表示的数组,下标从1开始,一直到n
PARENT(t):节点t的父节点,即floor(t/2)
RIGHT(t):节点t的左孩子节点,即:2*t
LEFT(t):节点t的右孩子节点,即:2*t+1
HEAP_SIZE(A):A当前的元素数目
下面给出其主要的四个操作(以大顶为例):
2.1 Heapify(A,n,t)
该操作主要用于维持的基本性质。假定以RIGHT(t)和LEFT(t)为根的子树都已经是,然后调整以t为根的子树,使之成为

复制代码 代码如下:


void Heapify(int A[], int n, int t)

{

int left = LEFT(t);

int right = RIGHT(t);

int max = t;

if(left <= n) max = A[left] > A[max] ? left : max;

if(right <= n) max = A[right] > A[max] ? right : max;

if(max != A[t])

{

swap(A, max, t);

Heapify(A, n, max);

}

}


2.2 BuildHeap(A,n)
该操作主要是将数组A转化成一个大顶。思想是,先找到的最后一个非叶子节点(即为第n/2个节点),然后从该节点开始,从后往前逐个调整每个子树,使之称为,最终整个数组便是一个

复制代码 代码如下:


void BuildHeap(int A[], int n)

{

int i;

for(i = n/2; i<=n; i++)

Heapify(A, n, i);

}


2.3 GetMaximum(A,n)
该操作主要是获取中最大的元素,同时保持的基本性质。的最大元素即为第一个元素,将其保存下来,同时将最后一个元素放到A[1]位置,之后从上往下调整A,使之成为一个

复制代码 代码如下:


void GetMaximum(int A[], int n)

{

int max = A[1];

A[1] = A[n];

n–;

Heapify(A, n, 1);

return max;

}


2.4 Insert(A, n, t)
中添加一个元素t,同时保持的性质。算法思想是,将t放到A的最后,然后从该元素开始,自下向上调整,直至A成为一个大顶

复制代码 代码如下:


void Insert(int A[], int n, int t)

{

n++;

A[n] = t;

int p = n;

while(p >1 && A[PARENT(p)] < t)

{

A[p] = A[PARENT(p)];

p = PARENT(p);

}

A[p] = t;

return max;

}

3. 的应用

3.1 排序
的最常见应用是排序,时间复杂度为O(N lg N)。如果是从小到大排序,用大顶;从大到小排序,用小顶

3.2 在O(n lg k)时间内,将k个排序表合并成一个排序表,n为所有有序表中元素个数。

【解析】取前100 万个整数,构造成了一棵数组方式存储的具有小顶,然后接着依次取下一个整数,如果它大于最小元素亦即顶元素,则将其赋予顶元素,然后用Heapify调整整个,如此下去,则最后留在中的100万个整数即为所求 100万个数字。该方法可大大节约内存。
3.3 一个文件中包含了1亿个随机整数,如何快速的找到最大(小)的100万个数字?(时间复杂度:O(n lg k))

4. 总结

是一种非常基础但很实用的数据结构,很多复杂算法或者数据结构的基础就是,因而,了解和掌握这种数据结构显得尤为重要。

5. 参考资料

(1)经典算法教程《算法导论》

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 数据结构之堆详解 https://www.kuaiidc.com/75922.html

相关文章

发表评论
暂无评论