zoukankan      html  css  js  c++  java
  • 【基本数据结构之堆】-C++

    注意:这篇博客讲的是手写堆,喜欢用C++自带数据结构模拟的慎入
    今天我们来聊一聊一种奇怪 的数据结构:

    为什么说这个数据结构有点奇怪呢?
    先看看其他的在我眼里是正常的数据结构:
    队列(近似于排队)
    栈(类似于一个桶)
    数组(就是一组存储各种数据类型的集合(?))

    但是!

    堆这个东西有点奇怪,它模拟的是:

    完全二叉树。

    这就很让人摸不着头脑了emmmm
    后来去各种找资料 知道了它的模拟方式就是:
    堆的物理结构就是数组。堆的逻辑结构是一棵完全二叉树。树中每个结点与数组中存放该结点中值的那个元素相对应。如下图:

    尼玛这不就是给这棵树的结点编号存数组里吗(疯狂咆哮)
    接下来堆的特性我就找了一段资料如下,做了解就可以了:

    感觉说的有点多....下面进入代码实现部分。今天我们以小根堆为例来进行代码实现的讲解 .
    堆的基本操作:

    • 上浮(up)
    • 下沉(down)
    • 插入(insert)
    • 删除(del)
    • *建立(build)

    第一个是上浮(up)操作。
    上浮操作,顾名思义,就是将一个结点在树中的位置尽量往上浮
    代码实现用到了【位运算】不了解的可以百度一下◀〓〓
    基本思路:
    以小根堆为例,当小根堆的元素值h[x]变小时,该结点可能会上浮,如果h[x]小于h[x>>1]则交换两个结点的值,如此循环下去直到x=1或h[x]>=h[x>>1].
    e.g.


    代码实现:

    void up(int x)//h[x]上浮
    {
       while (x>1&&h[x]<h[x>>1]){
           swap(h[x],h[x>>1]);
           x>>=1;
       }
    }
    

    时间复杂度为O(logn)。
    下沉(down)操作:
    思路:
    当小根堆的元素值h[x]变大时,该结点可能会下沉,如果有儿子结点值小于该结点的值则跟较小儿子结点交换,如此循环下去直到条件不满足或者没有儿子结点。
    代码:

    void down(int x)//h[x]下沉,len是堆中元素个数
    {
        int y=x<<1;
        while(y<=len){
             if(y+1<=len&&h[y+1]<h[y])y++;
             if(h[y]<h[x]){
                   swap(h[x],h[y]);
                   x=y;y=x<<1;
             }
             else break;
        }
    }
    

    O(logn)
    插入(insert)操作:
    基本思路:
    插入一个元素,把该元素放在最后,再做up操作。
    程序如下:

    void insert(int x)
    {
       h[++len]=x;
       up(len);
    }
    

    时间复杂度为O(logn)

    删除(del)操作:
    基本思路:
    删除第x个元素,为了不破坏堆的性质,把h[len]移到x处,堆元素个数len减一,注意可能是做up(x)也可能做down(x),根据h[x]的变化情况来定。
    程序如下:

    void del(int x)//删除h[x]
    {
        h[x]=h[len--];
        up(x);
        down(x);
    }
    

    时间复杂度为O(logn)
    *建堆(build)操作

    不做过多讲述,这个操作写法有很多,也可以尝试着自己去探索其他的写法!
    ov.

    个人博客地址: www.moyujiang.com 或 moyujiang.top
  • 相关阅读:
    onmouseover事件
    ref:ThinkPHP Builder.php SQL注入漏洞(<= 3.2.3)
    ref:mysql命令大全
    ref:mysql丢失密码,如何修改?
    ref:学习笔记 UpdateXml() MYSQL显错注入
    转:[译]CSV 注入:被人低估的巨大风险
    转:深入剖析 JavaScriptCore
    转:Exploiting Electron RCE in Exodus wallet
    转:LNMP虚拟主机PHP沙盒绕过/命令执行(php exec命令被禁之后)
    转:Ubuntu16.04下配置php+vscode+xdebug开发环境
  • 原文地址:https://www.cnblogs.com/moyujiang/p/11252523.html
Copyright © 2011-2022 走看看