00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "common.h"
00028 #include "quickHeap.h"
00029
00030 static char const rcsid[] = "$Id: quickHeap.c,v 1.1 2005/10/21 05:36:08 galt Exp $";
00031
00032
00033 struct quickHeap *newQuickHeap(int initSize,
00034 int (*compare )(const void *elem1, const void *elem2))
00035
00036
00037 {
00038 struct quickHeap *h;
00039 if (initSize < 1)
00040 errAbort("invalid initial size for newQuickHeap: %d",initSize);
00041 AllocVar(h);
00042 h->heapCount=0;
00043 h->heapMax = initSize;
00044 h->heap = AllocN(void *,h->heapMax);
00045 h->compareFunc = compare;
00046 return h;
00047 }
00048
00049
00050 void freeQuickHeap(struct quickHeap **pH)
00051
00052 {
00053 struct quickHeap *h = *pH;
00054 freez(&h->heap);
00055 freez(pH);
00056 }
00057
00058 static void expandQuickHeap(struct quickHeap *h)
00059
00060 {
00061 int newSize = h->heapMax * 2;
00062 ExpandArray(h->heap, h->heapMax, newSize);
00063 h->heapMax = newSize;
00064 }
00065
00066 void addToQuickHeap(struct quickHeap *h, void *elem)
00067
00068 {
00069 int n, p;
00070 if (h->heapCount >= h->heapMax)
00071 expandQuickHeap(h);
00072
00073 n = h->heapCount;
00074 h->heap[h->heapCount++] = elem;
00075 p = (n-1)/2;
00076 while (n > 0 && h->compareFunc(h->heap[p], h->heap[n]) < 0)
00077 {
00078 void *temp = h->heap[p];
00079 h->heap[p] = h->heap[n];
00080 h->heap[n] = temp;
00081 n = p;
00082 p = (n-1)/2;
00083 }
00084 }
00085
00086
00087 static void quickHeapBalanceWithChildren(struct quickHeap *h, int n)
00088
00089 {
00090 int c1, c2, hc;
00091 if (n < 0 || n >= h->heapCount)
00092 errAbort("attempt to quickHeapBalanceWithChildren with invalid value "
00093 "for n: %d, heapCount=%d", n, h->heapCount);
00094
00095
00096 hc = h->heapCount;
00097 c1 = 2*n+1;
00098 c2 = 2*n+2;
00099 while (TRUE)
00100 {
00101 void *temp = NULL;
00102 int bestc = n;
00103 if (c1 < hc && h->compareFunc(h->heap[c1], h->heap[bestc]) > 0)
00104 bestc = c1;
00105 if (c2 < hc && h->compareFunc(h->heap[c2], h->heap[bestc]) > 0)
00106 bestc = c2;
00107 if (bestc == n)
00108 break;
00109 temp = h->heap[bestc];
00110 h->heap[bestc] = h->heap[n];
00111 h->heap[n] = temp;
00112 n = bestc;
00113 c1 = 2*n+1;
00114 c2 = 2*n+2;
00115 }
00116 }
00117
00118
00119 void quickHeapTopChanged(struct quickHeap *h)
00120
00121 {
00122
00123
00124 quickHeapBalanceWithChildren(h,0);
00125 }
00126
00127 boolean quickHeapEmpty(struct quickHeap *h)
00128
00129 {
00130 return h->heapCount < 1;
00131 }
00132
00133 static void removeFromQuickHeapN(struct quickHeap *h, int n)
00134
00135
00136
00137 {
00138 if (n < 0 || n >= h->heapCount)
00139 errAbort("attempt to removeFromQuickHeapN with invalid value "
00140 "for n: %d, heapCount=%d", n, h->heapCount);
00141 h->heap[n] = h->heap[--h->heapCount];
00142 h->heap[h->heapCount] = NULL;
00143
00144
00145 if (n < h->heapCount)
00146 quickHeapBalanceWithChildren(h,n);
00147 }
00148
00149
00150 static int findElemInQuickHeap(struct quickHeap *h, void *elem)
00151
00152
00153 {
00154 int n = -1;
00155 while (++n < h->heapCount)
00156 {
00157 if (h->heap[n] == elem)
00158 return n;
00159 }
00160 return -1;
00161 }
00162
00163
00164 boolean removeFromQuickHeapByElem(struct quickHeap *h, void *elem)
00165
00166
00167
00168 {
00169 int n = findElemInQuickHeap(h, elem);
00170 if (n < 0)
00171 return FALSE;
00172 removeFromQuickHeapN(h,n);
00173 return TRUE;
00174 }
00175
00176 void *peekQuickHeapTop(struct quickHeap *h)
00177
00178 {
00179 if (h->heapCount < 1)
00180 return NULL;
00181 return h->heap[0];
00182 }
00183
00184 void *removeQuickHeapTop(struct quickHeap *h)
00185
00186
00187
00188 {
00189 void *result = h->heap[0];
00190
00191 if (h->heapCount > 0)
00192 {
00193 removeFromQuickHeapN(h,0);
00194 }
00195 return result;
00196 }
00197