ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/maxheap.c
Revision: 2.1
Committed: Wed Aug 12 23:07:59 2015 UTC (8 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Added Jan Wienold's evalglare to distribution

File Contents

# User Rev Content
1 greg 2.1 #include <stdio.h>
2     #include <stdlib.h>
3    
4     #include "maxheap.h"
5    
6    
7     static int resize_heap(maxHeap* hp,int sz)
8     {
9     int i;
10    
11     if (sz == hp->cap)
12     return 1;
13     hp->heap = (heapElem*) realloc(hp->heap,sz*sizeof(heapElem));
14     if (!hp->heap)
15     return 0;
16     for(i=hp->size;i<sz;i++) {
17     hp->heap[i].entity = NULL;
18     hp->heap[i].key = -HUGE;
19     }
20     hp->cap = sz;
21     if (sz < hp->size) {
22     hp->size = sz;
23     hp->state = HP_INVALID;
24     }
25     if (sz == 0) {
26     hp->heap = NULL;
27     hp->state = HP_BUILD;
28     }
29     return 1;
30     }
31    
32     int mheap_init(maxHeap* hp)
33     {
34     hp->size = 0;
35     hp->cap = 0;
36     hp->heap = NULL;
37     hp->state = HP_BUILD;
38     return resize_heap(hp,HP_STARTCAP);
39     }
40    
41     void mheap_free(maxHeap* hp)
42     {
43     resize_heap(hp,0);
44     free(hp);
45     }
46    
47     maxHeap* mheap_create()
48     {
49     maxHeap* res = (maxHeap*) calloc(1,sizeof(maxHeap));
50     if (!res) {
51     fprintf(stderr,"Error allocating heap struct\n");
52     return NULL;
53     }
54     if (!mheap_init(res))
55     return NULL;
56     return res;
57     }
58    
59    
60     static void swap_elem(heapElem* e1,heapElem* e2)
61     {
62     heapElem e;
63    
64     e = *e1;
65     *e1 = *e2;
66     *e2 = e;
67     }
68    
69     static void heapify(maxHeap* hp,int i)
70     {
71     int l,r,m;
72    
73     l = mh_left(i);
74     r = mh_right(i);
75     if ((l < hp->size) && (hp->heap[l].key > hp->heap[i].key))
76     m = l;
77     else
78     m = i;
79     if ((r < hp->size) && (hp->heap[m].key < hp->heap[r].key))
80     m = r;
81     if (m != i) {
82     swap_elem(&(hp->heap[m]),&(hp->heap[i]));
83     heapify(hp,m);
84     }
85     }
86    
87     void mheap_build(maxHeap* hp)
88     {
89     int i;
90    
91     for(i=((int) hp->size/2)-1;i>=0;i--)
92     heapify(hp,i);
93     hp->state = HP_BUILD;
94     }
95    
96     void mheap_sort(maxHeap* hp)
97     {
98     int i,sz;
99    
100     if (hp->state == HP_SORTED)
101     return;
102     if (hp->state != HP_BUILD)
103     mheap_build(hp);
104     sz = hp->size;
105     for(i=(hp->size-1);i>0;i--) {
106     swap_elem(&(hp->heap[0]),&(hp->heap[i]));
107     hp->size--;
108     heapify(hp,0);
109     }
110     hp->size = sz;
111     hp->state = HP_SORTED;
112     }
113    
114    
115     heapElem mheap_remove_max(maxHeap* hp)
116     {
117     heapElem res;
118     if (hp->size < 1) {
119     res.key = -HUGE;
120     res.entity = NULL;
121     return res;
122     }
123     res = hp->heap[0];
124     hp->heap[0] = hp->heap[hp->size - 1];
125     hp->size--;
126     heapify(hp,0);
127     return res;
128     }
129    
130     static int inc_key(maxHeap* hp,int i,g3Float k)
131     {
132     if (k < hp->heap[i].key) {
133     fprintf(stderr,"New key error in inc_key(mheap)\n");
134     hp->state = HP_INVALID;
135     return 0;
136     }
137     hp->heap[i].key = k;
138     while((i > 0) && (hp->heap[mh_parent(i)].key < hp->heap[i].key)) {
139     swap_elem(&(hp->heap[mh_parent(i)]),&(hp->heap[i]));
140     i = mh_parent(i);
141     }
142     return 1;
143     }
144    
145     int mheap_insert(maxHeap* hp,g3Float key,void* entity)
146     {
147     if (hp->size == hp->cap) {
148     if (!resize_heap(hp,hp->cap*2)) {
149     hp->state = HP_INVALID;
150     return 0;
151     }
152     }
153     hp->heap[hp->size].entity = entity;
154     hp->heap[hp->size].key = -HUGE;
155     hp->size++;
156     return inc_key(hp,(hp->size - 1),key);
157     }
158    
159    
160     #ifdef TEST_MHEAP
161     #include "timeutil.h"
162    
163     int main(int argc,char** argv)
164     {
165     g3Float* k;
166     int i,n;
167     maxHeap* hp;
168     heapElem e;
169     double t;
170     hp = mheap_create();
171    
172     if (argc > 1)
173     n = atoi(argv[1]);
174     else
175     n = 10;
176    
177     t = get_time();
178     for(i=0;i<n;i++) {
179     k = (g3Float*) malloc(sizeof(g3Float));
180     *k = 10.0*rand()/RAND_MAX;
181     if (!mheap_insert(hp,*k,k)) {
182     fprintf(stderr,"Error inserting\n");
183     return EXIT_FAILURE;
184     }
185     }
186     t = get_time() - t;
187     fprintf(stderr,"insert: %d %f\n",n,t);
188     t = get_time();
189     mheap_sort(hp);
190     t = get_time() - t;
191     fprintf(stderr,"sort: %d %f\n",n,t);
192     for(i=0;i<n;i++)
193     printf("%d %f \n",i,hp->heap[i].key);
194     printf("-------------\n");
195     t = get_time();
196     mheap_build(hp);
197     t = get_time() - t;
198     fprintf(stderr,"build: %d %f\n",n,t);
199     for(i=0;i<n;i++) {
200     e = mheap_remove_max(hp);
201     printf("%d %f \n",hp->size,e.key);
202     if ((i < (n-1)) && (e.key < mheap_get_max(hp).key)) {
203     fprintf(stderr,"oooops: not sorted\n");
204     }
205     }
206     return EXIT_SUCCESS;
207     }
208    
209     #endif