【每日一题】堆的任意位置的调整

发布于:2023-01-04 ⋅ 阅读:(300) ⋅ 点赞:(0)

文章目录

在这里插入图片描述

题目描述


以插入的方式来建堆实际上是O(NlogN),而O(N)的建堆方式就是向下调整算法完成的。
堆排序算法描述及时间复杂度分析

h的话就是heap堆,size就是当前存了多少个元素,指向下一个可以存放的位置。
ph存储的是插入的第k个数以及对应在h数组当中下标的映射;
hp存储的是堆里面的每一个点是第k个元素。

删除一个任意位置的元素,如果已经定位到该元素的位置,那么只需要swap(a[i],a[size]),然后将a[i]这个位置的元素进行向上或者向下调整,因为交换过后的元素可能比当前元素大也可能比当前元素小,但是走向上调整或者向下调整一遍就能得到答案。
修改的操作也是如此。直接修改当前元素,然后向上或者向下调整。

  • n 就是一直在增大,ph数组不会往回头看,因为k是不断增大的。
  • _size 就是最后一个元素
  • ph的下标标识当前节点是第k个插入的元素,ph中的元素不会被覆盖,并且由于k是不断增大的,所以ph数组会一直往后走。
  • hp数组是堆当中的元素到ph的映射,由于增删改,所以hp当中的元素就会一直发生变化(hp.size() == h.size())。但只需要当前元素能够找到对应ph的下标即可,得知自己是第k个元素插入的即可。(这个是交换元素的需求,因为两个元素交换的时候也需要更改ph表,标识插入的次序的改变)。
    在这里插入图片描述
    ph的下标就是第K+1个插入的元素,如0位置就是第一个。

在这里插入图片描述

每一次调整都是需要heap_swap,维护三个数组的关系。

题解


#include<iostream>
using namespace std;
#include<string>

const int N = 100010;
int h[N];
int hp[N];//heap -> p
int ph[N];//p -> heap
int _size = 0;//遍历到第几个元素
void heap_swap(int parent, int child)
{
    swap(ph[hp[parent]], ph[hp[child]]);
    swap(hp[parent], hp[child]);
    swap(h[parent], h[child]);
}

void AdjustUp(int child)//key标识元素
{
    int parent = (child - 1) / 2;
    while (child > 0)
    {
        if (h[parent] > h[child])
        {
            heap_swap(parent, child);
            child = parent;
            parent = (child - 1) / 2;
        }
        else break;
    }

}
//小堆
void AdjustDown(int parent)
{
    int child = parent * 2 + 1;
    while (child < _size)
    {
        if (child + 1 < _size && h[child] > h[child + 1])
        {
            child++;
        }
        if (h[parent] > h[child])
        {
            heap_swap(parent, child);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}
int main()
{
    int m;
    cin >> m;
    int n = 0;
    while (m--)
    {
        string str;
        cin >> str;
        if (str == "I")
        {
            int k;
            cin >> k;
            int child = _size;
            h[child] = k;
            ph[n] = _size;
            hp[_size] = n;
            AdjustUp(_size);
            ++_size;
            ++ n;
        }
        else if (str == "PM")
        {
            cout << h[0] << endl;
        }
        else if (str == "DM")
        {
            heap_swap(0,_size - 1);
            _size--;
            AdjustDown(0);
        }
        else if (str == "D")
        {
            int k;
            cin >> k;
            k = ph[k - 1];
            heap_swap(k, _size - 1);
            --_size;
            AdjustUp(k);
            AdjustDown(k);
        }
        else
        {
            int k, x;
            cin >> k >> x;
            k = ph[k - 1];
            h[k] = x;
            AdjustDown(k);
            AdjustUp(k);
        }
    }
    return 0;
}



end

  • 喜欢就收藏
  • 认同就点赞
  • 支持就关注
  • 疑问就评论
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到