型別名稱: 最小堆(minheap)
資料物件集: 完全二叉樹,每個結點的元素值不大於其子結點的元素值
最大堆同理可得
是不是堆要注意從根結點到任意結點路徑上結點序列的有序性!
另外 ,關於堆,為了保證陣列第乙個元素就是heap的根節點, heap基本上都是用陣列(或者其他的連續儲存空間)作為其儲存結構的。
2.1 堆的定義
//堆的定義
typedef
struct min_heap
min_heap_t;
關於p,由realloc分配,malloc分配的記憶體是位於堆,realloc則對malloc申請的記憶體進行大小的調整
p陣列元素為event*,n表示目前儲存了多少個元素,a表示p指向的記憶體的尺寸。
其中結構體event定義了min_heap_idx
struct event
2.2 典型小根堆與libevent中的差別heap[size++]
//下面就是 shift_up()的**邏輯,不斷的將 new 向上調整
_child = size;
while(_child>0) // 迴圈
// 下面就是 shift_up()的**邏輯,不斷的將 new 的「預留位置」向上調整
_hole = size; // _hole 就是為 new 預留的位置,但並不立刻將 new 放上
while(_hole>0) // 迴圈
heap[_hole] = new; // 調整結束,將 new 插入到_hole 指示的位置
size++; // 元素個數+1
2.3 **例項 - 最小堆的操作 之插入
知道了libevent中與典型最小堆的不同外,以上面的插入為例補充libevent中最小堆的**操作
檢查調整記憶體空間大小 –> 呼叫shift_up_插入
static inline int min_heap_push(min_heap_t* s, struct
event* e);
int min_heap_push(min_heap_t* s, struct
event* e)
libevent中的 min_heap_shift_up_
從上調整,其中,s->p[index]->min_heap_idx 為event結構體的min_heap_idx
void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e)
(s->p[hole_index] = e)->min_heap_idx = hole_index;
}
2.4 **例項 - 最小堆的操作 之取出
大部分時候,從堆裡取元素只侷限於取根節點。取完後,需要重新調整樹使其依然為乙個heap。
0;}
min_heap_shift_down_ 函式進行向下調整
/* hole_index 為取出的元素的位置,e為最右最下的元素值 */
void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e)
/* 執行第二步過程,將最右最下的節點插到空缺處 */
min_heap_shift_up_(s, hole_index, e);
}
//file : minheap-internal.h
#ifndef _min_heap_h_
#define _min_heap_h_
#include "event2/event.h"
#include "event2/event_struct.h"
#include "event2/util.h"
//堆的定義
typedef
struct min_heap
min_heap_t;
//static inline 內聯函式,c++中的巨集定義,提高函式呼叫效率
static
inline
void min_heap_ctor(min_heap_t* s);
static
inline
void min_heap_dtor(min_heap_t* s);
static
inline
void min_heap_elem_init(struct event* e);
static
inline
int min_heap_elem_greater(struct event *a, struct event *b);
static
inline
int min_heap_empty(min_heap_t* s);
static
inline
unsigned min_heap_size(min_heap_t* s);
static
inline
struct event* min_heap_top(min_heap_t* s);
static
inline
int min_heap_reserve(min_heap_t* s, unsigned n); //調整記憶體空間大小
static
inline
int min_heap_push(min_heap_t* s, struct event* e); //進堆
static
inline
struct event* min_heap_pop(min_heap_t* s); //堆首
static
inline
int min_heap_erase(min_heap_t* s, struct event* e);
static
inline
void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e); //向上調整
static
inline
void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e); //向下調整
int min_heap_elem_greater(struct event *a, struct event *b)
void min_heap_ctor(min_heap_t* s) //建立
void min_heap_dtor(min_heap_t* s) //刪除
void min_heap_elem_init(struct event* e)
int min_heap_empty(min_heap_t* s)
unsigned min_heap_size(min_heap_t* s)
struct event* min_heap_top(min_heap_t* s)
int min_heap_push(min_heap_t* s, struct event* e)
struct event* min_heap_pop(min_heap_t* s)
return0;}
int min_heap_erase(min_heap_t* s, struct event* e)
return -1;
}int min_heap_reserve(min_heap_t* s, unsigned n)
return0;}
void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e)
(s->p[hole_index] = e)->min_heap_idx = hole_index;
}void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e)
min_heap_shift_up_(s, hole_index, e);
}#endif /* _min_heap_h_ */
參考文章: libevent中的時間管理 時間快取與校正
上一文章中,知道在libevent中,用了小根堆對timer事件進行管理,其key值對應事件 的超時時間,從小根堆中可以取出最小的超時時間 對於timer,libevnet有乙個時間管理機制,即下面要說到的等待時間管理,時間快取校正等 static int timeout next struct e...
時間管理的小技巧
這裡分享一下我現在用的時間管理小技巧。看過一些書,覺得很多都是講理論性的東西,感覺說的都是因為我生也有涯,事情無限多,所以要將有限的生命集中在對自己最重要的事情上,隨之而來的就是 1 先做重要且緊急的 2 再做重要不緊急的 3 再做緊急不重要的 4 最後再做不緊急也不重要的。那麼現在問題來了,什麼事...
時間管理的小技巧(續)
接著前面時間管理小技巧裡的討論,說說拖沓的問題,就我個人來說,拖沓主要由兩個原因組成 1.這個事情實在是不情願做,比如跟客戶吵架 2.今天很累,沒心思幹活 對於第一點,最好就是授權出去,讓別人做,例如推給老闆,例如指派下屬解決。如果實在是逃不掉,就盡早做,所謂早死早超生。對於第二點,如果這個事情處理...