大小堆 - topK 问题

/*
* func: min topK sort 
* create by jsf20211118
*/

#include<stdio.h>
#include<stdlib.h>

struct max_heap{
        size_t n;
        size_t size;
        long long *p; //begin with index == 1
};

static void inline swap(long long *a, long long *b){
        long long c = *a;
        *a = *b;
        *b = c;
}

//pre condition heap(1, n - 1)
//post condition heap(1, n)
static void sift_up(long long *p, size_t n){
        size_t j, i;
        for(i = n; i > 1 && p[j=i/2] < p[i]; i = j){
                swap(&p[j], &p[i]);
        }
}

//pre condition heap(2, n)
//post condition heap(1, n)
static void sift_down(long long *p, size_t n){
        int i, c;
        for(i = 1; (c = 2 * i) <= n; i = c){
                if(c+1 <= n && p[c+1] > p[c]){
                        //left child big than right child, select left child to swap
                        c++;
                }
                if(p[i] > p[c]){
                        break;
                }
                swap(&p[i], &p[c]);
        }
}

struct max_heap * max_heap_init(size_t n){
        if(n == 0) return NULL;
        struct max_heap *ph = calloc(1, sizeof(struct max_heap));
        if (ph == NULL) {
                return NULL;
        }
        long long *p = calloc(n + 1, sizeof(long long));
        if (p == NULL) {
                free(ph);
                return NULL;
        }
        ph->size = n;
        ph->n = 0;
        ph->p = p;
        return ph;
}

void max_heap_finit(struct max_heap *ph){
        if(ph == NULL){
                return;
        }
        if(ph->p){
                free(ph->p);
                ph->p = NULL;
        }
        free(ph);
        ph = NULL;
}

void max_heap_reset(struct max_heap *ph){
        if(ph == NULL) return;
        ph->n = 0;
        return;
}

//insert max heap
//return -1 insert failed
//return 0 insert ok, *out == bigest value in the pre max heap
int max_heap_insert(struct max_heap *ph, long long in, long long *out){
        if(ph == NULL) return -1;
        long long *pdata = ph->p;
        size_t n = ph->n;
        //heap spcace full
        if(n == ph->size){
                if(in >= pdata[1]) return -1;
                if(out != NULL) *out = pdata[1];
                pdata[1] = in;
                sift_down(pdata, ph->size);
                return 0;
        }
        //heap still have space left
        ++(ph->n);
        pdata[ph->n] = in;
        sift_up(pdata, ph->n);
        if(out != NULL) *out = pdata[1];
        return 0;
}

int max_heap_extractmax(struct max_heap *ph, long long *out){
        if(ph == NULL || ph->n == 0) return -1;
        long long *pdata = ph->p;
        if(out != NULL) *out = pdata[1];
        pdata[1] = pdata[ph->n];
        --(ph->n);
        sift_down(pdata, ph->n);
        return 0;
}

int main(){
        long long a[15] = {5,4,55,3,0,22,3,3,3,4,6,42,69,-1,0};
        struct max_heap *ph = max_heap_init(5);
        if(ph == NULL) return -1;

        max_heap_reset(ph);

        int i = 0;
        for(i = 0; i < sizeof(a)/sizeof(a[0]); ++i){
                max_heap_insert(ph, a[i], NULL);
        }

        long long v;
        while(0 == max_heap_extractmax(ph, &v)){
                printf("min:%lld ", v);
        }
        printf("\n");

    max_heap_reset(ph);
        long long aa[5] = {5,4,55, -1, -1};
        for(i = 0; i < sizeof(aa)/sizeof(aa[0]); ++i){
                max_heap_insert(ph, aa[i], NULL);
        }

        while(0 == max_heap_extractmax(ph, &v)){
                printf("min:%lld ", v);
        }
        printf("\n");

    max_heap_reset(ph);
        long long aaa[1] = {5};
        for(i = 0; i < sizeof(aaa)/sizeof(aaa[0]); ++i){
                max_heap_insert(ph, aaa[i], NULL);
        }


        while(0 == max_heap_extractmax(ph, &v)){
                printf("min:%lld ", v);
        }
        printf("\n");

    max_heap_reset(ph);
        long long aaaa[6] = {5};
        for(i = 0; i < sizeof(aaaa)/sizeof(aaaa[0]); ++i){
                max_heap_insert(ph, aaaa[i], NULL);
        }


        while(0 == max_heap_extractmax(ph, &v)){
                printf("min:%lld ", v);
        }
        printf("\n");

        max_heap_reset(ph);
        long long *b = malloc(70000000*sizeof(long long));
        if(b == NULL){
        printf("malloc error\n");
        return -1;
        }
        b[70000] = -1; b[7] = -2; b[69999999] = -9;
        for(i = 0; i < 70000000; ++i){
                max_heap_insert(ph, b[i], NULL);
        }

        while(0 == max_heap_extractmax(ph, &v)){
                printf("min:%lld ", v);
        }
        printf("\n");

        max_heap_finit(ph);
        return 0;
}
 

参考:《编程珠玑》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值