堆排序 - 优先队列(实现)

优先队列:

优先队列的实现是大顶堆(优先级最高的元素再前面),对于节点数量为n的大顶堆,插入元素与弹出元素的时间复杂读为O(log(n)),询问的时间复杂度为O(1)。



首先我们需要将数组映射到完全二叉树上。

对于数组[16, 7, 3, 20, 17, 8]映射为:

从后到前调整非叶子节点与子节点的位置:

对于大小为n的二叉树,需要调整的第一个节点为n/2号节点。

为了方便理解我们以16(7,3)表示父亲节点为16,子节点从左到右以此为7,3。

步骤1:调整原始完全二叉树。

1.3(8),子节点8比3大调整为8(3)。

2.7(20,17),子节点20比7大调整为20(7,17)

3.16(20,8),调整为20(16,8)

4.16(7,17),调整为17(7,16)

最后得到:

步骤二:当我们需要查看最大元素时,我们只需要返回Tree[1],(节点1即可,也就是根节点)

步骤三:当我们需要插入最大元素时,Tree[++n] = new Node Value,然后通过步骤1类似调整,得到所需完全二叉树。

步骤四:删除最大元素时,我们仅需要将树的大小缩小为n-1,将节点n与1进行交换,后对树进行更新.

C++实现:

#include <iostream>
#include <cstring>

using namespace std;
#define N 100005
int heap[N];
int n,u;
int size = 0;
void swap(int &x,int &y){
    int t=x;
    x=y;
    y=t;
    return ;
}
void Up_update(int t){
    while(t>1){
        if(heap[t]>heap[t/2]){
            swap(heap[t],heap[t/2]);
            t/=2;
        }
        else return ;
    }
    return ;
}
void Down_update(int p){
    while(p<=size){
        int son=p*2;
        if(son<n&&heap[son]<heap[son+1])son++;
        if(heap[p]<heap[son]){
            swap(heap[p],heap[son]);
            p=son;
        }
        else return ;
    }return ;
}
int Get_Max(){
    return heap[1];
}
int main(){
    cin>>n;
    /**
     当我们需要将数组中n个整数插入堆时,我们只需要插入到最后,然后向上更新。
     **/
    for(int i=0;i<n;i++){
        cin>>u;
        heap[++size] = u;
        Up_update(size);
    }
    cout<<Get_Max()<<endl;
    /**
     * 当我们需要添加元素时我们仅需要将添加元素向上更新;
     * **/
     cin>>u;
     heap[++size] = u;
     Up_update(size);
     /**
      * 当我们需要删除优先级最大元素时,我们需要将heap[size]与heap[1]进行交换,数组大小缩小为size - 1
      * 向下更新
      * */
      swap(heap[1],heap[size]);
      size --;
      Down_update(1);
      /**
       * 当我们需要得到最大元素时,我们只需要输出heap[0]。
       * */
       cout<<Get_Max()<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值