堆排序

推荐:https://www.acwing.com/solution/content/120483/

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int A[100100],n,m,r;

void down(int u){
    int t = u;
    if(2*u<=r&&A[2*u]<A[t])t=2*u;//找节点小的,交换,t是记录最小的节点
    if(2*u+1<=r&&A[2*u+1]<A[t])t=2*u+1;
    if(t!=u){
        swap(A[t],A[u]);//交换然后递归操作
        down(t);
    }
    
}

int main()
{
    cin >> n >> m;
    r = n;
    for (int i = 1; i <= n; i ++ ){
        cin >> A[i];
    }
    for(int i = n/2; i >= 1; i--){
        down(i);//从最后一个节点开始
    }
    while(m--){
        cout << A[1] << " ";
        swap(A[1],A[r]);
        r--;//不断输出最顶上的也就是最小的
        down(1);
    }
    return 0;
}

模拟堆

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
//每次改变后要对交换来的元素做上浮或者下沉,如果没做可能是因为本来就在其下或上
using namespace std;

vector<int> heap;
vector<int> idxtime;
vector<int> timeidx;//维护一个是次数的索引,一个是索引的次数,方便交换的时候直接查找。

int k=1;

void heap_swap(int a, int b){
    swap(heap[a],heap[b]);
    swap(timeidx[idxtime[a]],timeidx[idxtime[b]]);
    swap(idxtime[a],idxtime[b]);
}

void down(int u){
    int t=u;
    if(2*u<heap.size()&&heap[2*u]<heap[t])t=2*u;
    if(2*u+1<heap.size()&&heap[2*u+1]<heap[t])t=2*u+1;
    if(t!=u){
        heap_swap(t,u);
        down(t);
    }
}

void up(int u){
    while(u/2>0&&heap[u]<heap[u/2]){
        heap_swap(u,u/2);
        u = u/2;
    }
}

void ins(int a){
    heap.push_back(a);
    timeidx.push_back(0);
    idxtime.push_back(0);
    timeidx[k] = heap.size()-1;
    idxtime[heap.size()-1] = k;
    up(heap.size()-1);
    k++;//记得递增
}

int main()
{
    int n;
    cin >> n;
    string op;
    int a,b;
    heap.push_back(0);
    idxtime.push_back(0);
    timeidx.push_back(0);
    
    while (n -- ){
        cin >> op;
        if(op=="I"){
            cin >> a;
            ins(a);
        }
        else if(op=="PM"){
            cout << heap[1] << endl;
        }
        else if(op=="DM"){
            heap_swap(1,heap.size()-1);
            heap.pop_back();
            idxtime.pop_back();
            if(heap.size() > 1)down(1);//每次交换后要对交换来的元素做上浮或者下沉,这里不up是因为是1
        }
        else if(op=="D"){
            cin >> a;
            int x = timeidx[a];//最后是卡在这里,应该用个临时变量,不然会变
            heap_swap(x,heap.size()-1);
            heap.pop_back();
            idxtime.pop_back();
            if(heap.size() > x){down(x);up(x);}            
        }
        else if(op=="C"){
            cin >> a >> b;
            heap[timeidx[a]] = b;
            up(timeidx[a]);
            down(timeidx[a]);
        }
    }
    return 0;
    
}
posted @ 2025-08-02 19:05  .N1nEmAn  阅读(5)  评论(0)    收藏  举报