Annotation of embedaddon/bird2/lib/heap.h, revision 1.1.1.1
1.1 misho 1: /*
2: * UCW Library -- Universal Heap Macros
3: *
4: * (c) 2001 Martin Mares <mj@ucw.cz>
5: * (c) 2005 Tomas Valla <tom@ucw.cz>
6: *
7: * This software may be freely distributed and used according to the terms
8: * of the GNU Lesser General Public License.
9: */
10:
11: /**
12: * [[intro]]
13: * Introduction
14: * ------------
15: *
16: * Binary heap is a simple data structure, which for example supports efficient insertions, deletions
17: * and access to the minimal inserted item. We define several macros for such operations.
18: * Note that because of simplicity of heaps, we have decided to define direct macros instead
19: * of a <<generic:,macro generator>> as for several other data structures in the Libucw.
20: *
21: * A heap is represented by a number of elements and by an array of values. Beware that we
22: * index this array from one, not from zero as do the standard C arrays.
23: *
24: * Most macros use these parameters:
25: *
26: * - @type - the type of elements
27: * - @num - a variable (signed or unsigned integer) with the number of elements
28: * - @heap - a C array of type @type; the heap is stored in `heap[1] .. heap[num]`; `heap[0]` is unused
29: * - @less - a callback to compare two element values; `less(x, y)` shall return a non-zero value iff @x is lower than @y
30: * - @swap - a callback to swap two array elements; `swap(heap, i, j, t)` must swap `heap[i]` with `heap[j]` with possible help of temporary variable @t (type @type).
31: *
32: * A valid heap must follow these rules:
33: *
34: * - `num >= 0`
35: * - `heap[i] >= heap[i / 2]` for each `i` in `[2, num]`
36: *
37: * The first element `heap[1]` is always lower or equal to all other elements.
38: *
39: * [[macros]]
40: * Macros
41: * ------
42: */
43:
44: /* For internal usage. */
45: #define HEAP_BUBBLE_DOWN_J(heap,num,less,swap) \
46: for (;;) \
47: { \
48: _l = 2*_j; \
49: if (_l > num) \
50: break; \
51: if (less(heap[_j],heap[_l]) && (_l == num || less(heap[_j],heap[_l+1]))) \
52: break; \
53: if (_l != num && less(heap[_l+1],heap[_l])) \
54: _l++; \
55: swap(heap,_j,_l,x); \
56: _j = _l; \
57: }
58:
59: /* For internal usage. */
60: #define HEAP_BUBBLE_UP_J(heap,num,less,swap) \
61: while (_j > 1) \
62: { \
63: _u = _j/2; \
64: if (less(heap[_u], heap[_j])) \
65: break; \
66: swap(heap,_u,_j,x); \
67: _j = _u; \
68: }
69:
70: /**
71: * Shuffle the unordered array @heap of @num elements to become a valid heap. The time complexity is linear.
72: **/
73: #define HEAP_INIT(heap,num,type,less,swap) \
74: do { \
75: uint _i = num; \
76: uint _j, _l; \
77: type x; \
78: while (_i >= 1) \
79: { \
80: _j = _i; \
81: HEAP_BUBBLE_DOWN_J(heap,num,less,swap) \
82: _i--; \
83: } \
84: } while(0)
85:
86: /**
87: * Delete the minimum element `heap[1]` in `O(log(n))` time.
88: * The removed value is moved just after the resulting heap (`heap[num + 1]`).
89: **/
90: #define HEAP_DELMIN(heap,num,type,less,swap) \
91: do { \
92: uint _j, _l; \
93: type x; \
94: swap(heap,1,num,x); \
95: num--; \
96: _j = 1; \
97: HEAP_BUBBLE_DOWN_J(heap,num,less,swap); \
98: } while(0)
99:
100: /**
101: * Insert `heap[num]` in `O(log(n))` time. The value of @num must be increased before.
102: **/
103: #define HEAP_INSERT(heap,num,type,less,swap) \
104: do { \
105: uint _j, _u; \
106: type x; \
107: _j = num; \
108: HEAP_BUBBLE_UP_J(heap,num,less,swap); \
109: } while(0)
110:
111: /**
112: * If you need to increase the value of `heap[pos]`, just do it and then call this macro to rebuild the heap.
113: * Only `heap[pos]` can be changed, the rest of the array must form a valid heap.
114: * The time complexity is `O(log(n))`.
115: **/
116: #define HEAP_INCREASE(heap,num,type,less,swap,pos) \
117: do { \
118: uint _j, _l; \
119: type x; \
120: _j = pos; \
121: HEAP_BUBBLE_DOWN_J(heap,num,less,swap); \
122: } while(0)
123:
124: /**
125: * If you need to decrease the value of `heap[pos]`, just do it and then call this macro to rebuild the heap.
126: * Only `heap[pos]` can be changed, the rest of the array must form a valid heap.
127: * The time complexity is `O(log(n))`.
128: **/
129: #define HEAP_DECREASE(heap,num,type,less,swap,pos) \
130: do { \
131: uint _j, _u; \
132: type x; \
133: _j = pos; \
134: HEAP_BUBBLE_UP_J(heap,num,less,swap); \
135: } while(0)
136:
137: /**
138: * Delete `heap[pos]` in `O(log(n))` time.
139: **/
140: #define HEAP_DELETE(heap,num,type,less,swap,pos) \
141: do { \
142: uint _j, _l, _u; \
143: type x; \
144: _j = pos; \
145: swap(heap,_j,num,x); \
146: num--; \
147: if (less(heap[_j], heap[num+1])) \
148: HEAP_BUBBLE_UP_J(heap,num,less,swap) \
149: else \
150: HEAP_BUBBLE_DOWN_J(heap,num,less,swap); \
151: } while(0)
152:
153: /**
154: * Default swapping macro.
155: **/
156: #define HEAP_SWAP(heap,a,b,t) (t=heap[a], heap[a]=heap[b], heap[b]=t)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>