• 二叉堆------小根堆


    二叉堆是完全二叉树,每个结点中存有一个元素。
    小根堆堆性质:父亲的权值不大于儿子的权值。

    插入操作
    插入操作是指向二叉堆中插入一个元素,要保证插入后也是一棵完全二叉树。

    最简单的方法就是,最下一层最右边的叶子之后插入。
    如果最下一层已满,就新增一层。

    向上调整:如果这个结点的权值大于它父亲的权值,就交换,重复此过程直到不满足或者到根。
    可以证明,插入之后向上调整后,没有其他结点会不满足堆性质。
    向上调整的时间复杂度是log(n)。

    删除操作
    删除操作指删除堆中最大的元素,即删除根结点。
    但是如果直接删除,则变成了两个堆,难以处理。
    所以不妨考虑插入操作的逆过程,设法将根结点移到最后一个结点,然后直接删掉。
    然而实际上不好做,我们通常采用的方法是,把根结点和最后一个结点直接交换。
    于是直接删掉(在最后一个结点处的)根结点,但是新的根结点可能不满足堆性质

    向下调整:在该结点的儿子中,找一个最小的,与该结点交换,重复此过程直到底层。
    可以证明,删除并向下调整后,没有其他结点不满足堆性质。
    时间复杂度log(n) 。

    应用:
    寻找数组中第K个最小的元素

    BinHeapMin.h

    #pragma once

    #include

    class BinHeapMin
    {
    public:
        BinHeapMin();
        ~BinHeapMin();
        bool Insert(int k);
        bool Delete(int k);
        int GetIndex(int k);
        void show();

    private:
        static const int CAPACITY;
        int *prique;
        int size;
    };

    const int BinHeapMin::CAPACITY = 100;

    BinHeapMin::BinHeapMin()
    {
        prique = new int[CAPACITY];
        size = 0;
    }

    BinHeapMin::~BinHeapMin()
    {
        if (prique != nullptr)
        {
            delete[] prique;
            prique = nullptr;
        }
    }

    bool BinHeapMin::Insert(int k)
    {
        if (size >= CAPACITY)
            return false;

        //percolate up
        int parent = (size - 1) / 2;
        int curIndex = size;

        while (curIndex > 0 && k <= prique[parent])
        {
            prique[curIndex] = prique[parent];
            curIndex = parent;
            parent = (parent - 1) / 2;
        }
        prique[curIndex] = k;

        ++size;

        return true;
    }

    int BinHeapMin::GetIndex(int k)
    {
        if (size == 0)
            return -1;

        for (int i = 0; i < size; ++i)
            if (prique[i] == k )
                return i;

        return -1;
    }

     

    bool BinHeapMin::Delete(int k)
    {
        if (size == 0)
            return false;

        int targetIndex = GetIndex(k);
        if (targetIndex < 0)
            return false;

        int lastElem = prique[--size];
        //percolate down
        int child = 2 * targetIndex + 1;
        int parent = targetIndex;
        while (child < size)
        {
            // find smaller child
            if ((child + 1) < size && prique[child] > prique[child + 1])
                ++child;

            // percolate one level
            if (lastElem > prique[child])
                prique[parent] = prique[child];
            else
                break;

            parent = child;
            child = 2 * child +1;
        }
        prique[parent] = lastElem;

        return true;
    }

    void BinHeapMin::show()
    {
        for (int i = 0; i < size; ++i)
            std::cout << prique[i] << " ";
        std::cout << std::endl;
    }

    BinHeapMin.cpp

    #include "BinHeapMin.h"

    int main()
    {
        BinHeapMin prique;
        int arr[] = { 13, 14, 16, 19, 21, 19, 68, 65, 26, 32, 31 };
        for (int i = 0; i < sizeof(arr) / sizeof(int); ++i)
        {
            prique.Insert(arr[i]);
        }
        prique.show();

        std::cout << "After delete 13" << std::endl;
        prique.Delete(13);
        prique.show();

        return 0;
    }
     

    13 14 16 19 21 19 68 65 26 32 31
    After delete 13
    14 19 16 26 21 19 68 65 31 32

  • 相关阅读:
    K8S(1)Pod
    力扣 -- 1049. 最后一块石头的重量 II(01背包问题)
    将labelImg生成的指定xml标签中某一类的检测框复制给其他图片的xml
    IDE应用kotlin官方编码规范并配置阿里java开发规约插件
    LeetCode--200. 岛屿数量(C++描述)
    python+nodejs+php+springboot+vue 导师双选系统
    BlobDetector的使用与参数说明(OpenCV/C++)
    深度学习基础知识 最近邻插值法、双线性插值法、双三次插值算法
    SAP 电商云 Assisted Service Module (ASM) 功能模块讲解
    HDC.Cloud Day | 全国首场上海站告捷,聚开发者力量造梦、探梦、筑梦
  • 原文地址:https://blog.csdn.net/cai0612123/article/details/126302064