什么是堆?

  这里的堆不是指计算机里的“堆栈”,而是指一种数据结构,它的结构是一颗二叉树。
我们把一个关键码集合中所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足以下两个之一:

  • 任一个节点的关键码均小于等于它的左右孩子的关键码,位于堆顶的关键码最小的称为最小堆;
  • 任一个节点的关键码均大于等于它的左右孩子的关键码,位于堆顶的关键码最大的称之为最大堆。

堆的创建

这里创建一个最小堆:

堆的插入和删除

由于堆的每次插入都在已经建好的最小堆的后面插入,但插入之后,还需要对堆进行自下而上的调整。

堆的删除:从堆顶中删除堆顶元素。移除堆顶元素后,用堆的最后一个结点填补堆顶元素,并将元素个数减一,在对堆进行自上而下的调整。

堆的应用

  1. 优先级队列:优先级队列的底层实现就是堆。
  2. 在一堆数据中找最大的前K个:先将前K个数据按照小堆进行创建,在依次遍历要查找的数据,如果该数据大于堆顶元素,则用它替换堆顶元素,并将堆调整,这样最终就可以得到最大的K个元素。
  3. 堆排序:如果是升序,我们需要创建一个大堆,利用和删除元素类似的想法,我们将堆顶元素和最后一个互换没然后调整堆,最终就可以得到一个升序的序列;反之,排列降序,就创建小堆。

下面是代码实现:

#include <iostream>
#include <vector>
using namespace std;

template <class T>
struct Less//小堆
{
    bool operator()(const T& left,const T& right)
    {
        return left->_data < right->_data;
    }
}; 

template <class T>
struct Greater//大堆
{
    bool operator()(const T& left,const T& right)
    {
        return left > right;
    }
};

template <class T,class Compare = Less<T>>
class Heap
{
public:
    Heap()
    {}
    Heap(T *arr,size_t size)
    {
        _arr.resize(size);
        for (size_t i = 0; i < size; i++)
            _arr[i] = arr[i];
        if (size > 1)
        {
            int root = (size - 2) / 2;//size_t的数据大于等于0造成死循环
            for (; root >= 0; root--)
                _AdjustDown(root);
        }
    }

    void Push(const T& data)
    {
        _arr.push_back(data);
        size_t size = _arr.size();
        if (size > 1)
            _AdjustUp(size - 1);
    }

    void Pop()
    {
        size_t size = _arr.size();
        if (_arr.empty())
            return;
        swap(_arr[0],_arr[size - 1]);
        _arr.pop_back();
        if (_arr.size() > 1)
            _AdjustDown(0);
    }

    bool Empty()const
    {
        return _arr.empty();
    }

    size_t Size()const
    {
        return _arr.size();
    }

    T Top()const
    {
        return _arr[0];
    }

private:
    void _AdjustDown(size_t parent)
    {
        size_t child = parent * 2 + 1;
        size_t size = _arr.size();
        while (child < size)
        {
            if (child + 1 < size && Compare()(_arr[child + 1],_arr[child]))
                child += 1;
            if (Compare()(_arr[child],_arr[parent]))
            {
                swap(_arr[parent],_arr[child]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
                break;
        }
    }

    void _AdjustUp(size_t child)
    {
        size_t parent = (child - 1) / 2;
        size_t size = _arr.size();
        while (child > 0)
        {
            if (Compare()(_arr[child],_arr[child]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
                break;
        }
    }
private:
    vector<T> _arr;
};

【数据结构】堆的更多相关文章

  1. 使用canvas实现黑客帝国数字雨效果

    这篇文章主要介绍了使用canvas实现黑客帝国数字雨效果,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧

  2. ios – Swift:递归值类型

    我有一个结构,我想要一个结构类型的全局变量?这个例子本质上是我实际创建的结构的简化版本.但是,它会抛出错误:有没有办法解决这个问题?

  3. swift篇第一期:简单的数据结构

    首先我们可以去使用Playground来编码,并且会实时的显示对应的编码信息,这样我们就不用每次都去运行程序来显示输出的东西了哦,也方便了我们对某些语句的验证,这个是比较赞的var与let前者为可变修饰符,后者为不可变从字面意思我们就可以很好的区分了常用的类型呢,跟其他语言基本相同啦,主要有几种:1.int类型2.Float,Double类型3.String类型4.Boolean类型当我们去声明一

  4. Swift 集合数据结构性能分析

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. Swift中的集合类数据结构

    在那种情况下,你将会需要一种基本的集合类数据结构。继续学习,你将会比较成熟的Cocoa数据结构与对应的纯Swift结构的性能。常见iOS数据结构iOS中三种最常用的数据结构是arrays,dictionaries和sets。除了在Swift和Objective-C中旧的Foundation框架中的数据结构,现在又有了新的仅支持Swift版本的数据结构与语言紧密结合在一起。Swift数组是同质的,意味着每一个Swift数组都只包含一种类型的对象。

  6. Swift基础篇——数组

    数组

  7. Swift——map函数浅析

    Swift语言的数组提供了一个map函数很好用,可建立一个a数组的映射数组b,即数学上的y=f.我为大家用代码来实现一下:输出结果如下:。输出结果分析:可以看到,我们对数组中的每一个元素都执行了+10操作,我们并没有进行遍历,然后再赋值给另一个新数组,可见使用map函数十分的方便。当然map函数的作用不限于此,不仅传递一个函数作为参数,还可以传递一个闭包表达式,代码如下:输出结果如下:。

  8. 11.Swift 中的类和结构体

    举例来说,以下情境中适合使用结构体:1.几何形状的大小,封装一个width属性和height属性,两者均为Double类型。这次就讲到这里,下次我们继续

  9. Swift快速入门之函数

    函数看一个函数的例子:实现两个数相加。函数必须以func开头,后面是函数名,小括号里是参数,箭头后面是返回类型。Swift中没有int之类的基本类型了,连表示数字都用类:Int。不论是类的方法或全局函数,语法一样。函数要通过return返回多个值在ObjC中是做不到的,当然你可以放到一个数组或字典中把这个数组或字典返回。return时,定义了一个元组对象,填入了两个数据的值。

  10. a place you can learn algorithms and data structures(算法和数据结构) in swift

    https://github.com/raywenderlich/swift-algorithm-club

随机推荐

  1. 【数据结构】单调栈

    显然,每个发射站发来的能量有可能被0或1或2个其他发射站所接受,特别是为了安全,每个发射站接收到的能量总和是我们很关心的问题。由于数据很多,现只需要你帮忙计算出接收最多能量的发射站接收的能量是多少。输入输出格式输入格式:第1行:一个整数N;第2到N+1行:第i+1行有两个整数Hi和Vi,表示第i个人发射站的高度和发射的能量值。输入输出样例输入样例:34235610输出样例:7题解中有讲解代码实现

  2. BZOJ 1798 [Ahoi2009] Seq 维护序列seq [线段树+多重标记下传]【数据结构】

    有长为N的数列,不妨设为a1,a2,…Input第一行两个整数N和P。第二行含有N个非负整数,从左到右依次为a1,aN,。表示把所有满足t≤i≤g的ai改为ai×c。操作2:“2tgc”。同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。Output对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。SampleInput7431234567512553242379313347SampleOutput2358HINT初始时数列为。对第5次操作,和为29+34+15+16=

  3. 陈越《数据结构》第一讲 基本概念

    陈越《数据结构》第一讲基本概念1什么是数据结构1.1引子例子:如何在书架上摆放图书?数据结构是:1.数据对象在计算机中的组织方式;2.数据对象必定与一系列加在其上的操作相关联;3.完成这些操作所用的方法就是算法。抽象数据类型数据类型-数据对象集;-数据集合相关联的操作集。抽象-与存放数据的机器无关;-与数据存储的物理结构无关;-与实现操作的算法和编程语言均无关。

  4. 陈越《数据结构》第二章 线性结构

    表中元素个数称为线性表的长度;线性表没有元素时,称为空表;表起始位置称表头,表结束位置称表尾。插入和删除操作只能在链栈的栈顶进行。

  5. 【数据结构】

    非线性结构:线性结构的元素之间具有线性关系,非线性结构中的元素之间不再是序列的关系,他们呈现的是更复杂的层次关系,即一个数据元素有且仅有一个直接前驱,但可有另个或者多个直接后继,显然比序列关系复杂常见非线性结构:树,图散列表PHP中的hashtable就是哈希表就是由数组和链表组成,一个长度为16的数组中,每个元素存储的是一个链表的头结点。

  6. 【数据结构】【C++STL】FIFO队列&amp;优先队列

    首先都需要打头文件queueFIFO队列是先进先出的就好像排队一样STL定义FIFO队列优先队列的话是有优先级存在的STL定义优先队列定义方式都是大根堆FIFO队列和优先队列都有一些操作COYG

  7. 【数据结构】 堆

    自底向上://增加/减少已有节点值Heap_Increase_Key//向堆插入新的节点HeapInsert自顶向下://替换堆顶后,维持堆函数KeepHeap//弹出堆顶函数Pop

  8. 【数据结构】链表

    线性表的顺序存储结构有存储密度高及能够随机存取等优点,但存在以下不足:线性表的链式存储(单链表)的实现单向循环链表的实现

  9. 伸展树(SPLAY)个人总结+模板 [平衡树]【数据结构】【模板】

    前言最近3个月内,无论是现场赛还线上赛中SPLAY出现的概率大的惊人啊啊啊!!!然而不会的我就GG了,同时发现大家都会SPLAY,,,,然后就学习了一波。——————————————————————————-附上整体代码-md贴上来太卡了,去题解里看吧维护序列的维护一堆数的

  10. BZOJ 1895 &amp; POJ 3580 supermemo [SPLAY]【数据结构】

    Ay}Ttimes.Forexample,performing“REVOLVE242”on{1,5}INSERTxP:insertPafterAx.Forexample,performing“INSERT24”on{1,5}DELETEx:deleteAx.Forexample,performing“DELETE2”on{1,5}MINxy:querytheparticipantwhatistheminimumnumberinsub-sequence{Ax…Ay}.Forexample,thecorrec

返回
顶部