|
Graphviz
2.29.20120523.0446
|
00001 /* $Id$Revision: */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 #include <memory.h> 00015 #include <stdio.h> 00016 00017 /* Priority queue: 00018 * To work, the following have to be defined before this file is 00019 * included: 00020 * - PQTYPE : type of object stored in the queue 00021 * - PQVTYPE : type of priority value 00022 * - N_VAL(pq,n) : macro for (negative) priority value of object n in pq 00023 * - N_IDX(pq,n) : macro for integer index > 0 of n in pq 00024 * - guard, type PQTYPE, with N_VAL(guard) == 0 00025 * 00026 * Priorities are stored as negative numbers, with the item with the least 00027 * negative priority at the head (just after the guard). 00028 */ 00029 00030 #ifdef PQ_TYPES 00031 typedef struct { 00032 PQTYPE* pq; 00033 int PQcnt; 00034 int PQsize; 00035 } PQ; 00036 #endif 00037 00038 #ifdef PQ_CODE 00039 static void 00040 PQgen(PQ* pq, int sz, PQTYPE guard) 00041 { 00042 pq->pq = N_NEW(sz+1,PQTYPE); 00043 pq->pq[0] = guard; 00044 pq->PQsize = sz; 00045 pq->PQcnt = 0; 00046 } 00047 00048 static void 00049 PQfree(PQ* pq, int freeAll) 00050 { 00051 free (pq->pq); 00052 if (freeAll) free (pq); 00053 } 00054 00055 static void 00056 PQinit(PQ* pq) 00057 { 00058 pq->PQcnt = 0; 00059 } 00060 00061 #ifdef PQCHECK 00062 static int 00063 PQcheck (PQ* pq) 00064 { 00065 int i; 00066 00067 for (i = 1; i <= pq->PQcnt; i++) { 00068 if (N_IDX(pq,pq->pq[i]) != i) { 00069 return 1; 00070 } 00071 } 00072 return 0; 00073 } 00074 #endif 00075 00076 static void 00077 PQupheap(PQ* ppq, int k) 00078 { 00079 PQTYPE* pq = ppq->pq; 00080 PQTYPE x = pq[k]; 00081 PQVTYPE v = N_VAL(ppq,x); 00082 int next = k/2; 00083 PQTYPE n; 00084 00085 while (N_VAL(ppq,n = pq[next]) < v) { 00086 pq[k] = n; 00087 N_IDX(ppq,n) = k; 00088 k = next; 00089 next /= 2; 00090 } 00091 pq[k] = x; 00092 N_IDX(ppq,x) = k; 00093 } 00094 00095 static int 00096 PQinsert(PQ* pq, PQTYPE np) 00097 { 00098 if (pq->PQcnt == pq->PQsize) { 00099 agerr (AGERR, "Heap overflow\n"); 00100 return (1); 00101 } 00102 pq->PQcnt++; 00103 pq->pq[pq->PQcnt] = np; 00104 PQupheap (pq, pq->PQcnt); 00105 #ifdef PQCHECK 00106 PQcheck(pq); 00107 #endif 00108 return 0; 00109 } 00110 00111 static void 00112 PQdownheap (PQ* ppq, int k) 00113 { 00114 PQTYPE* pq = ppq->pq; 00115 PQTYPE x = pq[k]; 00116 PQVTYPE v = N_VAL(ppq,x); 00117 int lim = ppq->PQcnt/2; 00118 PQTYPE n; 00119 int j; 00120 00121 while (k <= lim) { 00122 j = k+k; 00123 n = pq[j]; 00124 if (j < ppq->PQcnt) { 00125 if (N_VAL(ppq,n) < N_VAL(ppq,pq[j+1])) { 00126 j++; 00127 n = pq[j]; 00128 } 00129 } 00130 if (v >= N_VAL(ppq,n)) break; 00131 pq[k] = n; 00132 N_IDX(ppq,n) = k; 00133 k = j; 00134 } 00135 pq[k] = x; 00136 N_IDX(ppq,x) = k; 00137 } 00138 00139 static PQTYPE 00140 PQremove (PQ* pq) 00141 { 00142 PQTYPE n; 00143 00144 if (pq->PQcnt) { 00145 n = pq->pq[1]; 00146 pq->pq[1] = pq->pq[pq->PQcnt]; 00147 pq->PQcnt--; 00148 if (pq->PQcnt) PQdownheap (pq, 1); 00149 #ifdef PQCHECK 00150 PQcheck(pq); 00151 #endif 00152 return n; 00153 } 00154 else return pq->pq[0]; 00155 } 00156 00157 static void 00158 PQupdate (PQ* pq, PQTYPE n, PQVTYPE d) 00159 { 00160 N_VAL(pq,n) = d; 00161 PQupheap (pq, N_IDX(pq,n)); 00162 #ifdef PQCHECK 00163 PQcheck(pq); 00164 #endif 00165 } 00166 00167 #ifdef DEBUG 00168 00169 static void 00170 PQprint (PQ* pq) 00171 { 00172 int i; 00173 PQTYPE n; 00174 00175 fprintf (stderr, "Q: "); 00176 for (i = 1; i <= pq->PQcnt; i++) { 00177 n = pq->pq[i]; 00178 fprintf (stderr, "(%d:%f) ", N_IDX(pq,n), N_VAL(pq,n)); 00179 } 00180 fprintf (stderr, "\n"); 00181 } 00182 #endif 00183 #endif 00184
1.7.5