堆排序(小根堆)

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std ;

int h[100000] ;
int n ;

void siftdown(int i) //i为要调整的根节点
{
    int flag = 1,t ; //flag用来标记是否还需要继续调整
    while(2*i <= n && flag)   //是否至少有左子树
    {
        if(h[2*i]<h[i])
            t = 2*i ;
        else t = i ;

        if(2*i+1 <= n)  //如果也有右子树
        {
            if(h[2*i+1]<h[t])
                t = 2*i+1 ;
        }
        if(i != t)  //如果子树比根节点小
        {
            int temp = h[i] ;
            h[i] = h[t] ;
            h[t] = temp ;
            i = t ;    //将i赋值为最小的节点,方便继续操作
        }
        else flag = 0 ;   //已经不需要继续调整了
    }
}

void create()   //建立堆的函数,多次调用siftdown
{
    for(int i = n/2;i>=1;i--)
    {
        siftdown(i) ;
    }
    printf("小根堆创建成功\n") ;
}

int deleteMin()   //删除最大的元素
{
    int t = h[1] ;
    h[1] = h[n] ;
    n-- ;
    siftdown(1) ;
    return t ;
}

int main()
{
    printf("输入数字个数\n") ;
    int num ;
    scanf("%d",&num) ;
    n = num ;
    for(int i = 1 ;i<=num ;i++)
        //scanf("%d",&h[i]) ;
        h[i] = 100-i ;
    create() ;
    printf("正序排序后如下\n") ;
    for(int i = 1 ;i<=num;i++)
        printf("%d ",deleteMin()) ;
    return  0 ;
}

时间: 2024-10-14 07:52:39

堆排序(小根堆)的相关文章

堆排序—大根堆,小根堆

1.小根堆 若根节点存在左子女则根节点的值小于左子女的值:若根节点存在右子女则根节点的值小于右子女的值. 2.大根堆 若根节点存在左子女则根节点的值大于左子女的值:若根节点存在右子女则根节点的值大于右子女的值. 3.结论 (1)堆是一棵完全二叉树(如果公有h层,那么1~h-1层均满,在h层连续缺失若干个右叶子). (2)小根堆的根节点的值是最小值,大根堆的根节点的值是最大值. (3)堆适合于采用顺序存储. 4.堆的插入算法 将一个数据元素插入到堆中,使之依然成为一个堆. 算法描述:先将结点插入到

[大、小根堆应用总结一]堆排序的应用场景

前言 在整理算法题的时候发现,大根堆(小根堆)这种数据结构在各类算法中应用比较广泛,典型的堆排序,以及利用大小根堆这种数据结构来找出一个解决问题的算法最优解.因此,我打算单独将关于堆的应用独立总结出来,后面每遇到一种跟堆结构相关的应用都放到这个目录下. 堆的定义 n个关键字序列L[1-n]称为堆,当且仅当该序列满足: 1. L(i)<=L(2i)且L(i)<=L(2i+1)或 2. L(i)>=L(2i)且L(i)>=L(2i+1) 满足第一个条件的成为小根堆(即每个结点值小于它的

序列——堆排序-大根堆(堆大顶)

1.小根堆 如果根是儿童的存在留下的根值左孩子小于值:如果根是儿童的权利的存在的根值比他们的孩子的权利少值. 2.大根堆 如果根是儿童的存在留下的根值多名离开自己的孩子值.子女则根节点的值大于右子女的值. 3.结论 (1)堆是一棵全然二叉树(假设公有h层,那么1~h-1层均满,在h层连续缺失若干个右叶子). (2)小根堆的根节点的值是最小值,大根堆的根节点的值是最大值. (3)堆适合于採用顺序存储. 4.堆的插入算法 将一个数据元素插入到堆中,使之依旧成为一个堆. 算法描写叙述:先将结点插入到堆

堆排序——大根堆(大顶堆)

1.小根堆 若根节点存在左子女则根节点的值小于左子女的值:若根节点存在右子女则根节点的值小于右子女的值. 2.大根堆 若根节点存在左子女则根节点的值大于左子女的值:若根节点存在右子女则根节点的值大于右子女的值. 3.结论 (1)堆是一棵完全二叉树(如果公有h层,那么1~h-1层均满,在h层连续缺失若干个右叶子). (2)小根堆的根节点的值是最小值,大根堆的根节点的值是最大值. (3)堆适合于采用顺序存储. 4.堆的插入算法 将一个数据元素插入到堆中,使之依然成为一个堆. 算法描述:先将结点插入到

堆排序 &nbsp; 和 堆的大数据应用

//本次练习的是   堆排序   和  堆的大数据应用//堆排序的时间复杂度为   O(n)//堆的大数据应用应选择   小堆   进行处理//但  当数据超过100000时速度明显变慢,可能是建立小堆的时候慢   >>>>>有没有更优的方法 #include<iostream>#include<vector>#include<time.h>using namespace std; //........................以下为

用小根堆实现dijkstra,求图的单源最短路径

小根堆实现dijkstra 求图的最短路径,最常用的有四种方法: 1.Floyed(弗洛伊德)算法.最简单的最短路径算法,可以求多源最短路径.时间复杂度为O(n*n*n). 2.Dijkstra(迪杰斯特拉)算法.只能求单源最短路径.时间复杂度为O(n*n). 3.Bellman-Ford(贝尔曼福德)算法.只能求单源最短路径.时间复杂度为O(NE)(N为顶点数,E是边数). 4.SPFA算法.为Bellman-Ford算法的队列实现,减少不必要的冗杂计算.只能求单源最短路径.时间复杂度为O(k

bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——小根堆+大根堆+贪心

Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1<=Mi<=N)只. 他们希望从Si到Ei去.公交车只能座C(1<=C<=100)只奶牛.而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求.注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足. Input 第1行: 三个整数: K,N,C. 由空格隔开. 第2..

让priority_queue支持小根堆的几种方法

点击这里了解什么是priority_queue 前言 priority_queue默认是大根堆,也就是大的元素会放在前面 例如 #include<iostream> #include<cstdio> #include<queue> using namespace std; priority_queue<int>q; int a[15]={0,1,4,2,3,5}; const int n=5; int main() { for(int i=1;i<=n

scala写算法-用小根堆解决topK

topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简单的看成k次insert操作).然后从源数据中的第k个数据之后的每个元素与堆的根节点(小根堆得root是最小的)比较,如果小于root,那么直接pass;如果大于,则执行headp.deleteMin,然后把该元素插入堆中并再次保持堆序.保持堆序需要涉及上滤与下滤的过程. 样例为: object M