zoukankan      html  css  js  c++  java
  • 基本数据结构——二叉堆

    迅速补档,为A*做一下铺垫…

    概念定义

    二叉堆就是一个支持插入、删除、查询最值的数据结构。他其实是一棵完全二叉树。那么堆一般分为大根堆和小根堆

    大根堆

    树中的任意一个节点的权值都小于或者等于其父节点的权值,则称该二叉树满足大根堆性质。

    小根堆

    树中的任意一个节点的权值都大于或者等于其父节点的权值,则称该二叉树满足小根堆性质。

    习惯用法

    一般习惯把堆用数组保存。才用父子二倍的编号方式。即:对于某一个节点x,其左儿子节点为2*x,右儿子节点为x*2+1

    支持功能及代码实现

    Insert插入

    向二叉堆中插入一个节点。我们首先把这个节点放在堆的末尾,然后再向上层层递归更新。时间复杂度为O(log N)

    int heap[Size],n;
    void up(int p){
        while(p>1){
            if(heap[p]>heap[p/2]){
                swap(heap[p],heap[p/2]);
                p/=2;
            }
            else{
                break;
            }
        }
    }
    void Insert(int val){
        heap[++n]=val;
        up(n);
    } 

    注:编者在写这篇博文的时候,由于内容过于基础,所以手速大约为20迈。如若有代码错误,敬请指出与纠正。

    GetTop取首

    返回二叉堆堆顶的值,时间复杂度O(1)

    int GetTop(){
        return heap[1];
    }

    Extract去首

    操作原理是将堆首取出,然后与堆尾发生交换,然后通过自减操作删除堆尾,再进行一次向下更新。时间复杂度为O(log N)

    void Down(int p){
        int s=p*2;//p的左儿子
        while(s<=n){
            if(s<n&&heap[s]<heap[s+1]){
                s++;//取左右两儿子中较大者的编号 
            }
            if(heap[s]>heap[p]){
                swap(heap[s],heap[p]);
                //这里是大根堆,所以如果子节点大于父节点,是不满足性质的。
                p=s,s=p*2; 
            }
            else{
                break;
            }
        } 
    }
    void Extract(){
        heap[1]=heap[n--];
        down(1);
    }

    Remove删除

    这个操作实现把下标为p的节点删除。这玩意和Extract相似,把heap[p]和heap[n]交换,然后n自减。但这时候到底需要向下更新还是向上更新并不好说。所以我们两个都要。

    void Remove(int k){
        heap[k]=heap[n--];
        up(k);
        Down(k);
    }

    STL助你偷懒

    写了那么多废话,然而STL里有一个priority_queue(优先队列)实现了一个大根堆。支持push插入,top取首,pop去首。然而没有Remove这种定点删除的操作。考虑到A*算法用的是小根堆,这其实对A*并没什么卵用。保险起见…我去翻了一下小蓝书…发觉……

    STL可以实现小根堆,是我在口胡(口头胡扯)……

    虽然STL真的只支持大根堆…但是我们可以喂他吃一个魅惑菇啊!!

    就是说,我们通过重载“<”运算符,让STL认为大就是小,小即是大!你说的黑不是黑~

    那,为了防止我们正常使用"<",我们选择用结构体让他重载。

    struct rec{
        int id;
        double val;
    };
    bool operator <(const rec &a,const rec &b){
        return a.val>b.val;
    }

    题目中的Show Time

    啊只要你想到处都能Show,我还有事我先走了(逃)。

  • 相关阅读:
    读书笔记——读《构建之法:现代软件工程》第13~17章
    读《构建之法》十一,十二章有感
    男神女神配 社区交友网 —— 之 主页 详细解说
    典型用户和场景
    最终版本
    用户调研
    第9-11组总体评价
    第二次sprint
    读《构建之法》8-10章
    第一个Sprint
  • 原文地址:https://www.cnblogs.com/Uninstalllingyi/p/11222409.html
Copyright © 2011-2022 走看看