Chinaunix首页 | 论坛 | 博客
  • 博客访问: 138802
  • 博文数量: 25
  • 博客积分: 588
  • 博客等级: 中士
  • 技术积分: 292
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-10 18:18
文章分类

全部博文(25)

文章存档

2012年(7)

2011年(18)

我的朋友

分类: C/C++

2012-02-29 15:00:23

libevent中的min-heap,稍有改动。

  1. #include <stdlib.h>
  2. #include <time.h>

  3. using namespace std;
  4. #ifndef NULL
  5. #define NULL 0
  6. #endif
  1. #include
    long long timestamp() {
        struct timeval val;
        gettimeofday(&val, NULL);
        return val.tv_sec * 1000000LL + val.tv_usec;
    }

  2. typedef unsigned int uint32;
  3. typedef struct data_ {
  4.     int idx;
  5.     int da;
  6. }data_t;

  7. typedef struct min_heap {
  8.     data_t **p;
  9.     uint32 a, n;
  10. }min_heap_t;

  11. inline void min_heap_init(min_heap_t *s);
  12. inline void min_heap_uninit(min_heap_t *s);
  13. inline int min_heap_reserve(min_heap_t *s, uint32 n);

  14. inline uint32 min_heap_size(min_heap_t *s);

  15. inline int min_heap_push(min_heap_t *s, data_t *data);
  16. inline data_t *min_heap_pop(min_heap_t *s);
  17. inline data_t *min_heap_top(min_heap_t *s);
  18. inline int min_heap_erase(min_heap_t *s, data_t *data);
  19. inline data_t *min_heap_erase(min_heap_t *s, uint32 idx);
  20. inline void min_heap_shift_up(min_heap_t *s, uint32 hole_index, data_t *data);
  21. inline void min_heap_shift_down(min_heap_t *s, uint32 hole_index, data_t *data);

  22. void min_heap_init(min_heap_t *s) {
  23.     s->p = NULL;
  24.     s->n = s->a = 0;
  25. }

  26. void min_heap_uninit(min_heap_t *s) {
  27.     if (s->p) {
  28.         s->n = s->a = 0;
  29.         free(s->p);
  30.     }
  31. }

  32. uint32 min_heap_size(min_heap_t *s) {
  33.     return s->n;
  34. }

  35. int min_heap_push(min_heap_t *s, data_t *data) {
  36.     if (min_heap_reserve(s, s->n+1) < 0) {
  37.         return -1;
  38.     }
  39.     min_heap_shift_up(s, s->n++, data);
  40.     return 0;
  41. }

  42. data_t *min_heap_top(min_heap_t *s) {
  43.     if (s->n) {
  44.         return *s->p;
  45.     }
  46.     return NULL;
  47. }

  48. data_t *min_heap_pop(min_heap_t *s) {
  49.     if (s->n) {
  50.         data_t *d = *s->p;
  51.         min_heap_shift_down(s, 0u, s->p[--s->n]);
  52.         d->idx = -1;
  53.         return d;
  54.     }
  55.     return NULL;
  56. }

  57. int min_heap_erase(min_heap_t *s, data_t *data) {
  58.     if (data->idx > 0 && s->n > 0) {
  59.         data_t *last = s->p[--s->n];
  60.         uint32 parent = (data->idx - 1 ) / 2 ;
  61.         if (s->p[parent]->da > last->da) {
  62.             min_heap_shift_up(s, data->idx, last);
  63.         }
  64.         else {
  65.             min_heap_shift_down(s, data->idx, last);
  66.         }
  67.         data->idx = -1;
  68.         return 0;
  69.     }
  70.     else if (data->idx == 0 && min_heap_pop(s)) {
  71.         return 0;
  72.     }
  73.     return -1;
  74. }

  75. data_t* min_heap_erase(min_heap_t *s, uint32 idx) {
  76.     if (idx > 0 && idx < s->n) {
  77.         data_t *d = s->p[idx];
  78.         data_t *last = s->p[--s->n];
  79.         uint32 parent = (d->idx - 1) / 2;
  80.         if (s->p[parent]->da > last->da) {
  81.             min_heap_shift_up(s, d->idx, last);
  82.         }
  83.         else {
  84.             min_heap_shift_down(s, d->idx, last);
  85.         }
  86.         d->idx = -1;
  87.         return d;
  88.     }
  89.     else if (idx == 0) {
  90.         return min_heap_pop(s);
  91.     }
  92.     return NULL;
  93. }

  94. int min_heap_reserve(min_heap_t *s, uint32 n) {
  95.     if (s->a < n) {
  96.         data_t **p;
  97.         uint32 a = s->a ? s->a*2:8;
  98.         if (a < n) {
  99.             a = n;
  100.         }
  101.         p = (data_t**)realloc(s->p, a * sizeof(*p));
  102.         if (p == NULL) {
  103.             return -1;
  104.         }
  105.         s->p = p;
  106.         s->a = a;
  107.     }
  108.     return 0;
  109. }

  110. void min_heap_shift_up(min_heap_t *s, uint32 hole_index, data_t *data) {
  111.     uint32 parent = (hole_index - 1) / 2;
  112.     while (hole_index && s->p[parent]->da > data->da) {
  113.         s->p[hole_index] = s->p[parent];
  114.         s->p[hole_index]->idx = hole_index;
  115.         hole_index = parent;
  116.         parent = (hole_index - 1) / 2;
  117.     }
  118.     s->p[hole_index] = data;
  119.     data->idx = hole_index;
  120. }

  121. void min_heap_shift_down(min_heap_t *s, uint32 hole_index, data_t *data) {
  122.     uint32 min_child = 2 * (hole_index + 1);
  123.     while (min_child <= s->n) {
  124.         if (s->p[min_child]->da > s->p[min_child-1]->da) {
  125.             min_child--;
  126.         }
  127.         if (s->p[min_child]->da >= data->da) {
  128.             break;
  129.         }
  130.         s->p[hole_index] = s->p[min_child];
  131.         s->p[hole_index]->idx = hole_index;
  132.         hole_index = min_child;
  133.         min_child = 2 * (hole_index + 1);
  134.     }
  135.     data->idx = hole_index;
  136.     s->p[hole_index] = data;
  137. }

  138. int main(int argc, char **argv) {

  139.     min_heap_t *s = new min_heap_t;
  140.     printf("heap size:%d\n", min_heap_size(s));
  141.     vector<data_t*> vd;
  142.     long long t = timestamp();
  143.     for (int i = 0; i < 100; i++) {
  144.         data_t *d = new data_t;
  145.         d->da = rand() % 100;
  146.         fprintf(stderr, "i:%d\n", d->da);
  147.         vd.push_back(d);
  148.         min_heap_push(s, d);
  149.     }
  150.     printf("heap size:%d\n", min_heap_size(s));
  151.     for (int i = 0; i < vd.size(); i++) {
  152.         fprintf(stderr, "e:%d\n", min_heap_erase(s, vd[i]->idx)->da);
  153.     }

  154.     printf("%ll\n", timestamp() - t);
  155.     printf("heap size:%d\n", min_heap_size(s));

  156.     return 0;
  157. }

阅读(3025) | 评论(0) | 转发(1) |
0

上一篇:二叉查找树

下一篇:单向链表

给主人留下些什么吧!~~