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;
        }
    }

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

  • 相关阅读:
    23.Vue技术栈开发实战-Icon组件
    shell脚本每行后面多了一个^M的原因和解决办法
    mmap概述
    camera otp介绍
    brk实现
    USB技术浅析
    带你遨游USB世界
    echarts 更换主题颜色
    Hive UDAF介绍与开发
    2020湖北高考理科第一名唐楚玥的学习方法演讲
  • 原文地址:https://www.cnblogs.com/Alarak26/p/8503664.html
Copyright © 2011-2022 走看看