aboutsummaryrefslogtreecommitdiff
path: root/heap.c
diff options
context:
space:
mode:
Diffstat (limited to 'heap.c')
-rw-r--r--heap.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/heap.c b/heap.c
new file mode 100644
index 0000000..365d925
--- /dev/null
+++ b/heap.c
@@ -0,0 +1,152 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdbool.h>
4#include "util.h"
5
6typedef int T;
7
8// https://stackoverflow.com/a/22900767
9
10#define LEFT(idx) (idx*2+1)
11#define RIGHT(idx) (idx*2+2)
12#define PARENT(idx) ((idx-1)/2)
13
14static void
15swap(T heap[], int i, int j)
16{
17 T temp = heap[i];
18 heap[i] = heap[j];
19 heap[j] = temp;
20}
21
22static void
23fixup(T heap[], int i)
24{
25 int p = PARENT(i);
26
27 while ( i > 0 && heap[p] < heap[i] ) {
28 swap(heap, i, p);
29
30 i = p;
31 p = PARENT(i);
32 }
33}
34
35static void
36fixdown(T heap[], int i, int n)
37{
38 for ( ;; ) {
39 const int l = LEFT(i);
40 const int r = RIGHT(i);
41 int m = i;
42
43 if ( l < n && heap[m] < heap[l] )
44 m = l;
45
46 if ( r < n && heap[m] < heap[r] )
47 m = r;
48
49 if ( m == i )
50 break;
51
52 swap(heap, m, i);
53
54 i = m;
55 }
56}
57
58static void
59heapify(T heap[], int n)
60{
61 for ( int i = n / 2 - 1; i >= 0; --i )
62 fixdown(heap, i, n);
63}
64
65static void
66my_heapsort(T a[], int n)
67{
68 heapify(a, n);
69
70 for ( int i = n - 1; i >= 0; --i ) {
71 swap(a, 0, i);
72 fixdown(a, 0, i);
73 }
74}
75
76// -------------------------------------------
77
78struct pq { // Priority Queue
79 T heap[251];
80 int sz;
81};
82
83void
84pq_init(struct pq *pq)
85{
86 pq->sz = 0;
87}
88
89bool
90pq_push(struct pq *pq, T data)
91{
92 if ( pq->sz == NELEM(pq->heap) )
93 return false;
94
95 pq->heap[pq->sz] = data;
96 fixup(pq->heap, pq->sz);
97 ++pq->sz;
98 return true;
99}
100
101bool
102pq_pop(struct pq *pq, T* data)
103{
104 if ( pq->sz == 0 )
105 return false;
106
107 *data = pq->heap[0];
108 --pq->sz;
109 pq->heap[0] = pq->heap[pq->sz];
110 fixdown(pq->heap, 0, pq->sz);
111 return true;
112}
113
114// -------------------------------------------
115
116
117void print_heap(T heap[], int n)
118{
119 if ( n ) {
120 printf("%d", heap[0]);
121 for ( int i = 1; i != n; ++i )
122 printf(", %d", heap[i]);
123 putchar('\n');
124 }
125}
126
127int main(void)
128{
129#if 0 // Heap-Testprogramm
130 T heap[20] = { 18, 18, 16, 9, 7, 1, 9, 3, 7, 5 };
131
132 print_heap(heap, 10);
133
134 //heap[10] = 13; fixup(heap, 10);
135 swap(heap, 0, 9); fixdown(heap, 0, 9);
136
137 print_heap(heap, 9);
138#endif
139
140 struct pq pq[1];
141
142 pq_init(pq);
143
144 for ( int i = 0; i != 10; ++i )
145 pq_push(pq, rand());
146
147 T data;
148 while ( pq_pop(pq, &data) )
149 printf("%d\n", data);
150}
151
152