大根堆(模板)

Posted Styx-ferryman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大根堆(模板)相关的知识,希望对你有一定的参考价值。

今天学了大根堆,第一次从头到尾个人手打,虽说有些STL能代替堆但效率很低,算了算300000的数据甚至要跑500ms。。。。

也算记录一下吧。

自己的:83ms(300000)

%:pragma GCC optimize(3)
#include<bits/stdc++.h>
#define N 500010
#define INF 0x3f3f3f3f
using namespace std;

struct Heap
{
    int heap[N];
    int size;


void init()
{
    size=0;
}

void adjust_up(int i)//查找父亲节点是否比儿子节点小,如果有,交换,直到没有
{
    int fa=i>>1;
    if(fa<0)
    {
        return ;
    }
    if(heap[i]>heap[fa])
    {
        swap(heap[i],heap[fa]);
        adjust_up(fa);
    }
}

void adjust(int size,int i)//调整父亲和儿子节点,以保证父亲节点一定大于儿子
{
    int ls,rs,maxa;
    ls=i<<1;
    rs=i<<1|1;
    if(ls<=size&&heap[ls]>heap[i])
    {
        maxa=ls;
    }
    else
    {
        maxa=i;
    }
    if(rs<=size&&heap[rs]>heap[maxa])
    {
        maxa=rs;
    }
    if(heap[maxa]!=heap[i])
    {
        swap(heap[maxa],heap[i]);
        adjust(size,maxa);
    }

}



void push(int x)
{
    heap[size]=x;
    adjust_up(size);
    size++;
}

int top()
{
    return heap[0];    
}

void pop()
{
    swap(heap[0],heap[size]);
    size--;
    adjust(size,0);
}

bool empty()
{
    if(size<0)
    {
        return true;
    }
    return false;
}


};

int main()
{
    double time1;
    int i,j;
    srand(time(NULL));
    Heap my_heap;
    my_heap.init();
    clock_t startTime,endTime;  
    startTime = clock();  
    for(i=1;i<=300000;i++)
    {
        int x=rand()*rand();
        my_heap.push(x);
    }
    my_heap.size--;
    while(!my_heap.empty())
    {
        //printf("%d ",my_heap.top());
        my_heap.pop();
    }
    
    endTime = clock();  
    time1=(double)(endTime - startTime) / CLOCKS_PER_SEC;
    printf("%.6lf",time1);
    return 0;
}

 

老师的:71ms(300000)

#include <bits/stdc++.h>
using namespace std;

const int N = 300000;

struct Heap {
    int heap[N + 10];
    int size;

    void init() {
        size = 1;
    }

    void push (int x) {
        int i = size++;
        while (i > 1) {
            int p = (i >> 1);
            if (heap[p] > x) {
                break;
            }
            heap[i] = heap[p];
            i = p;
        }
        heap[i] = x;
    }

    int pop() {
        int ret = heap[1];
        int x = heap[--size];

        int i = 1;
        while ((i << 1) < size) {
            int lson = (i << 1);
            int rson = (i << 1 | 1);
            if (rson < size && heap[rson] > heap[lson]) lson = rson;

            if (heap[lson] < x) {
                break;
            } 

            heap[i] = heap[lson];
            i = lson;
        }
        heap[i] = x;
        return ret;
    }

    bool empty() {
        return size == 0;
    }
};

int a[N];

int main () {

    srand(time(NULL));


    Heap my_heap;
    my_heap.init();
    for (int i = 0; i < N; i++) {
        a[i] = rand()*rand();
    }

//start here
    clock_t mystart = clock();
    for (int i = 0; i < N; i++) {
        my_heap.push(a[i]);
    }

    while(!my_heap.empty()) {
        my_heap.pop();
    }

    clock_t myend = clock();
//end here

    priority_queue<int> heap;

    clock_t start = clock();
    for (int i = 0; i < N; i++) {
        heap.push(a[i]);
    }

    while(!heap.empty()) {
       // cout << heap.top() << endl;
        heap.pop();
    }

    clock_t end = clock();
    cout << "Running time of xjoi machine is:" << static_cast<double> (myend-mystart)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    cout << "Running time stl is:" << static_cast<double> (end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;

    return 0;
}

 

 

 

 

每天刷题身体棒棒!

以上是关于大根堆(模板)的主要内容,如果未能解决你的问题,请参考以下文章

大根堆

算法——堆排序(大根堆--升序)

堆-模板

算法大根堆

模板小根堆

堆排序