zoukankan      html  css  js  c++  java
  • 手写堆

    堆是一种特殊的数据结构,它通常是一个可以被看做一棵树的数组对象。这个数组以二叉树的形式来维护。注意:这个二叉树必须是完全二叉树。

    堆又分为小根堆和大根堆。顾名思义,小根堆就是每个父亲节点都小于等于其儿子节点;大根堆反之。

    而数据用堆存储时并不是随着数组下标增大数据有序增大或减小,而是以下边的方式存储:

    根节点下标=孩子下标/2
    左孩子下表=根节点下标*2+1
    右孩子下标=左孩子下标+1

    虽说c++STL提供了优先队列这种东西,但手写堆也有其自己的好处,例如灵活性高,运行快等。

    那么如何写堆呢?

    首先堆应该在其性质不变的前提下,支持返回堆顶,删除堆顶,插入元素

    返回堆顶:

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

    删除堆顶:

    void heap_pop()
    {
        heap[1]=heap[tot];
        tot--;
        now_x=1;
        while(1)
        {
            if((now_x<<1)>tot)
            break;
            if((now_x<<1)==tot)
            next_x=tot;
            else
            {
                if(heap[now_x<<1]<heap[(now_x<<1)+1])
                next_x=(now_x<<1);
                else
                next_x=(now_x<<1)+1;
            }
            if(heap[now_x]>heap[next_x])
            {
                swap(heap[now_x],heap[next_x]);
                now_x=next_x;
            }
            else
            break;
        }
    }

    插入元素:

    void heap_add(int x)
    {
        tot++;
        heap[tot]=x;
        now_x=tot;
        while(1)
        {
            if(heap[now_x]<heap[now_x>>1])
            {
                swap(heap[now_x],heap[now_x>>1]);
                now_x>>=1;
            }
            else
            break;
        }
    }

    维护原理:将父亲节点与子节点比较,若符合规则,则不变;否则交换它们两个的值。

  • 相关阅读:
    Abp集成Swagger的最佳实践
    ELK 集中日志分析 windows部署实战
    nuget国内镜像的解决办法
    nginx+Memcached 缓存设计
    OpenSSL windows 下编译
    HTTPS 双向认证构建移动设备安全体系
    ASP.NET vNext on CentOS 7
    XF custom render 各平台实现类
    Xamarin.Forms 简介
    【开篇】认识网络和传输,架构
  • 原文地址:https://www.cnblogs.com/Alarak26/p/8503664.html
Copyright © 2011-2022 走看看