数据结构之堆

本文介绍了堆排序的原理及其实现,包括小根堆的概念、操作方法如插入、删除、修改元素等,并提供了一个具体实例及代码实现,展示了如何使用小根堆找到整数数列中前m小的数。堆排序是一种效率较高的排序算法,适用于大规模数据的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆的介绍(heap)

小根堆

其父节点比两个孩子结点都小,大根堆则相反,上图显示的就是大根堆;

存储:

采用一维数组,对于某一个父节点x,其左儿子为2x,右儿子为2x+1,从下标1开始。

操作:

1.插入,即插入一个数

heap[++Size]=x;
up(Size);

2.集合当中的最小值
因为是小根堆,所以由定义可知最小值就是根。

heap[1];

3.删除最小值
采用的方式:最后一个元素覆盖第一个元素,然后总数减一;

heap[1]=heap[Size];
Size--;
down(1);

4.删除任意一个元素
同样采用尾元素覆盖的方法;

heap[k]=heap[Size];
Size--;
down(k);
up(k);

5.修改任意一个元素

heap[k]=x;
down(k);
up(k);

下面以一个具体的例子来看:

原题链接:堆排序

题目描述

输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。

输入格式

第一行包含整数 n 和 m。

第二行包含 n 个整数,表示整数数列。

输出格式

共一行,包含 m 个整数,表示整数数列中前 m 小的数。

数据范围

1≤m≤n≤105,
1≤数列中元素≤109
输入样例:

5 3
4 5 1 3 2

输出样例:

1 2 3

代码实现:

#include<iostream>

using namespace std;

const int N=1e5+100;
int n,m;
int h[N],a[N],Size;

void down(int u)
{
    //小根堆
    int t=u;
    if(2*u<=Size&&h[2*u]<h[t]) t=2*u;
    if(2*u+1<=Size&&h[2*u+1]<h[t]) t=2*u+1;
    if(u!=t)
    {
        swap(h[t],h[u]);
        down(t);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&h[i]);
    Size=n;
    //从n/2开始,是因为二叉树的性质
    for(int i=n/2;i;i--) down(i);
    while(m--)
    {
        printf("%d ",h[1]);
        h[1]=h[Size];
        Size--;
        down(1);
    }
    return 0;
}

总结:
1.小根堆对于元素的排序效率更高;
2.小根堆也就是STL中的优先队列;
3.原理实现方式值得仔细分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值