手写堆理解记录

本文介绍了堆排序的原理及两种不同的实现方式。第一种实现是基于完全二叉树的数组存储,通过调整堆来完成排序;第二种实现则展示了如何进行push和pop操作。堆排序是一种效率较高的排序算法,它利用了堆这种数据结构的特性,确保了在每次操作后都能保持堆的性质。文章提供了详细的代码示例,帮助读者理解并掌握堆排序的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆排序 

传送门

#include <iostream>
#include <algorithm>

using namespace std;
const int N =1000010;
int h[N];
int n,m,size;
void down(int i){
    int u=i;
    if(2*u<size&&h[2*u]<h[t])t=2*u;
    if(2*u+1<size&&h[2*u+1]<h[t])t=2*u+1;
    if(u!=t){
        swap(h[t],h[u]);
        down(t);
    }
}
int main(){
  cin>>n>>m;
  for(int i=1;i<=n;i++)
     cin>>h[i];
     size=n;
  for(int i=n/2;i;i--)down(i);
  while(m--){
      cout<<h[1];
      h[1]=h[size];
      size--;
      down(1);
  }
}

 用数组存储堆, 

如上都是来自https://www.acwing.com/大佬的解题模板 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
const int N =1e6+10;
int heap[N],size;
using namespace std;
int top(){
  return heap[1];
}
void push(int x){
  heap[++size]=x;
  int temp=size;
  while(temp>1){
    int next=temp>>1;
    if(heap[next]<=heap[temp])
      return ;
    swap(heap[next],heap[temp]);
    temp=next;
  }
}
void pop(){
  heap[1]=heap[size--];
  int temp=1;
  while(temp<<1<=size){
    int next=temp<<1;
    if(heap[next]>heap[next+1])
       next++;
    if(heap[temp]<=heap[next])
       return ;
    swap(heap[temp],heap[next]);
    temp=next;
  }
}
int main(){
  int n;
  cin>>n;
  for(int opt,x;n;n--){
    cin>>opt;
    switch(opt){
      case 1:{
        cin>>x;
        push(x);
        break;
      }
      case 2:{
        cout<<top()<<endl;
        break;
      }
      case 3:{
        pop();
      }
    }
  }
  return 0;
}

堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:

 

  • 堆中某个结点的值总是不大于或不小于其父结点的值

  • 堆总是一棵完全二叉树。

 

push操作

那么多的节点我们要插入到那里,不管插到那里我们还需要移动本来位置上的节点,所以我们索性直接插到树的最后面去,我们最需跟它的父节(tmep>>1)点作比较,若是小根堆的话,保证头节点最小就可以了

heap[++size]=x;
  int temp=size;
  while(temp>1){
    int next=temp>>1;
    if(heap[next]<=heap[temp])
      return ;
    swap(heap[next],heap[temp]);
    temp=next;
  }

pop操作

大佬们太绝了,我刚拿到这个还纠结把heap[1]去掉了,这个树如何重建尼,大佬们直接将堆的最后一个拉上来heap([1]=heap[size--]),然后让heap[1]往下走所有的顾虑就迎刃而解了 

heap[1]=heap[size--];
  int temp=1;
  while(temp<<1<=size){
    int next=temp<<1;
    if(heap[next]>heap[next+1])
       next++;
    if(heap[temp]<=heap[next])
       return ;
    swap(heap[temp],heap[next]);
    temp=next;
  }

赶紧去手撸下上面的那道裸题吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@居安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值