/*
* 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;
}
参考:《编程珠玑》