二叉堆相关操作及堆排序

#include <iostream>
#include <algorithm>
using namespace std;
int n,op,x,len;
//构建大根堆
void min_heapify(int arr[],int start,int end){
    int dad=start;
    int son=dad*2+1;
    while(son<=end){
        if (son+1<=end && arr[son]>arr[son+1])
        {
            son++;
        }
        if (arr[dad]<arr[son])
        {
            return ;
        } else {
            swap(arr[dad],arr[son]);
            dad=son;
            son=dad*2+1;
        }
    }
}
//建堆
void make_heap(int arr[],int len){
    //先对无序序列,构建堆。构建堆从下往上,从第一个非叶结点开始
    for (int i = len/2-1; i >= 0; --i)
    {
        min_heapify(arr,i,len-1);
    }
}
//进行堆排序
void heap_sort(int arr[],int len){
    make_heap(arr,len);
    // 堆排序的过程,根节点与最后一个叶子元素交换,再重新调整堆。如此循环往复
    for (int i = len-1; i > 0; --i)
    {
        swap(arr[0],arr[i]);
        min_heapify(arr,0,i-1);
    }
}
void push(int arr[],int x){
    //插入过程,先将元素放到末尾,然后上浮,与父节点比较,比父节点小就上浮
    arr[len++]=x;
    int now=len-1;
    while(now){
        // int dad=(now-1)/2;
        int dad=now>>1;
        cout << now << " " << dad << endl;
        if (arr[now]<arr[dad])
        {
            swap(arr[now],arr[dad]);
            now = dad;
        } else {
            break;
        }
    }
}
//删除操作
// 将堆顶元素与末尾元素交换,再调整堆
void pop(int arr[]){
    swap(arr[0],arr[len-1]);
    len--;
    int now=0;
    int son=now*2+1;//先是左
    while(son<len){
        if (son+1<len&&arr[son]>arr[son+1])
        {
            son++;
        }
        if (arr[now]>arr[son])
        {
            swap(arr[now],arr[son]);
        } else {
            break;
        }
        now=son;
        son=son*2+1;
    }
}
//本程序是小根堆相关操作
int main() {
    int arr[]={3,4,3,9,7,8,6,5};
    len = (int)sizeof(arr)/sizeof(int);
    make_heap(arr,len);
    cin>>n;
    while(n){
        n--;
        cin>>op;//op 1:插入x 2:查询堆顶元素 3:删除堆顶元素 4:堆排序-逆序
        switch(op){
            case 1:
                cin>>x;
                push(arr,x);
                break;
            case 2:
                cout<<arr[0]<<endl;
                break;
            case 3:
                pop(arr);
            case 4:
                heap_sort(arr,len);
                for (int i = 0; i < len; ++i)
                {
                    cout<<arr[i]<<" ";
                }
                cout<<endl;
                break;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值