zoukankan      html  css  js  c++  java
  • 最小堆的两种实现及其STL代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    bool cmp(int x,int y)
    {
        return x>y;
    }
    int main()
    {
        vector<int> a;
        int num,n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num);
            a.push_back(num);
        }
        make_heap(a.begin(),a.end(),cmp);
        scanf("%d",&num);
        a.push_back(num);
        push_heap(a.begin(),a.end(),cmp);
        cout<<a[0]<<endl;
        pop_heap(a.begin(),a.end(),cmp);
        a.pop_back();
        return 0;
    }

    pop_heap(a.begin(),a.end(),cmp)  的功能只是将第一个元素放到最后,然后忽略最后一个元素的情况下再维护一遍堆

    一:最小堆的初始堆有两种方式建立:

    1、for(int i=1;i<=m;++i)

         heap_up(i);

    让上面的路走通

    2、for(int i=m/2;i>=1;--i)
        heap_down(i);

    让下面的路走通

     

    二、删除最小元素

    将最后元素取代最小元素,然后heap_down(1)

    三、插入元素

    将元素放在数组最后,然后heap_up(m)

    //合并果子    方式一
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    int n;int ans=0;int m=0;//堆的大小 
    int a[10005];
    
    void heap_up(int d){
        int father;
        while(d>1)
        {
            father=d/2;
            if(a[father]>a[d])
            {
                swap(a[father],a[d]);
                d=father;
            }
            else break;
        }
    } 
    
    void heap_down(int d){
        int son;
        while(d<=m)
        {
            son=2*d;
            if(son>m) break;
            if(son+1<=m&&a[son+1]<a[son]) son++;
            if(a[son]<a[d])
            {
                swap(a[son],a[d]);
                d=son;
            }
            else break;
        }
    
    }
    
    int heap_pop(){
        int ret=a[1];
        a[1]=a[m--];
        heap_down(1);
        return ret;
    }
    
    void heap_push(int num){
        m++;
        a[m]=num;
        heap_up(m);
    }
    
    int main(){
        cin>>n;
        for(int i=1;i<=n;++i)
        {
            cin>>a[i];
            m++;
            heap_up(i);
        }
        
        
        for(int i=1;i<n;++i)
        {
            int min1=heap_pop();
            int min2=heap_pop();
            ans+=min1+min2;
            heap_push(min1+min2);
        
        }
        cout<<ans<<endl;
    
    }
    //合并果子  方式二
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    int n;int ans=0;int m=0;//堆的大小 
    int a[10005];
    
    void heap_up(int d){
        int father;
        while(d>1)
        {
            father=d/2;
            if(a[father]>a[d])
            {
                swap(a[father],a[d]);
                d=father;
            }
            else break;
        }
    } 
    
    void heap_down(int d){
        int son;
        while(d<=m)
        {
            son=2*d;
            if(son>m) break;
            if(son+1<=m&&a[son+1]<a[son]) son++;
            if(a[son]<a[d])
            {
                swap(a[son],a[d]);
                d=son;
            }
            else break;
        }
    
    }
    
    int heap_pop(){
        int ret=a[1];
        a[1]=a[m--];
        heap_down(1);
        return ret;
    }
    
    void heap_push(int num){
        m++;
        a[m]=num;
        heap_up(m);
    }
    
    int main(){
        cin>>n;
        for(int i=1;i<=n;++i)
        {
            cin>>a[i];
            m++;
        }
        
        for(int i=m/2;i>=1;--i)
        heap_down(i);
        
        for(int i=1;i<n;++i)
        {
            int min1=heap_pop();
            int min2=heap_pop();
            ans+=min1+min2;
            heap_push(min1+min2);
        
        }
        cout<<ans<<endl;
    
    }

     

  • 相关阅读:
    关于调试 SharePoint 2010 中的爬网问题的疑难解答提示
    JS 获取 本周、本月、本季度、本年、上月、上周、上季度、去年
    jqGrid动态列
    【原创】博客“缘”
    讀取內部網站8/22
    開啟VS2005速度慢8/25
    仲秋節快樂
    外部表不是預期的格式8/28
    要考試10/17
    DataTable導入Excel 8/27
  • 原文地址:https://www.cnblogs.com/noip/p/9516985.html
Copyright © 2011-2022 走看看