/* File MinPriorityQueue.c. */ #include "mcs360.h" #include "MinPriorityQueue.h" struct MinPriorityQueue { int size; /* Current size of MinPriorityQueue. */ int capacity; /* Allocated size of dynamic array. */ PQEntry *entry; /* Dynamic array for MinPriorityQueue entries. */ Boolean (*less)(PQEntry a, /* Pointer to function returning true if first */ PQEntry b); /* argument is treated as less than the second. */ }; #define INITIAL_CAPACITY 16 MinPriorityQueue *CreateMinPriorityQueue( Boolean (*less)(PQEntry,PQEntry)) { MinPriorityQueue *newPQ = (MinPriorityQueue *)checked_malloc(sizeof(MinPriorityQueue)); newPQ->size = 0; newPQ->capacity = INITIAL_CAPACITY; newPQ->entry = (PQEntry *)checked_malloc( newPQ->capacity * sizeof(PQEntry)); newPQ->less = less; return newPQ; } void DestroyMinPriorityQueue( MinPriorityQueue *pq) { free( pq->entry); free(pq); } void add( PQEntry item, MinPriorityQueue *pq) { int n; if (pq->size == pq->capacity ) { pq->entry = (PQEntry *)checked_realloc( pq->entry, 2*pq->capacity); pq->capacity *= 2; } ++pq->size; n = pq->size - 1; pq->entry[n] = item; while ( n > 0 && pq->less( pq->entry[n], pq->entry[(n-1)/2]) ) { PQEntry temp = pq->entry[n]; pq->entry[n] = pq->entry[(n-1)/2]; pq->entry[(n-1)/2] = temp; n = (n-1) / 2; } } PQEntry removeMin( MinPriorityQueue *pq) { int i, smallest; PQEntry minEntry = pq->entry[0]; pq->entry[0] = pq->entry[--pq->size]; i = 0; while ( 2*i+1 <= pq->size - 1 ) { smallest = i; if ( pq->less( pq->entry[2*i+1], pq->entry[i]) ) smallest = 2*i+1; if ( 2*i+2 <= pq->size-1 && less( pq->entry[2*i+2], pq->entry[smallest]) ) smallest = 2*i+2; if ( smallest != i ) { PQEntry temp = pq->entry[i]; pq->entry[i] = pq->entry[smallest]; pq->entry[smallest] = temp; i = smallest; } else i = pq->size; } return minEntry; } PQEntry min( const MinPriorityQueue *pq) { return pq->entry[0]; } Boolean empty( const MinPriorityQueue *pq) { return pq->size == 0; } int size( const MinPriorityQueue *pq) { return pq->size; }