/* File rprique.c Contains functions to manipulate an R-priority queue. An R-priority queue is a priority queue that, after initialization, permits only removal operations. The functions provided are:
initFromPartnStack: Initialize an R-priority queue to contain the points in a specified cell of the top partition on a specified partition stack.
removeMin: Removes the minimum point from an R-priority queue. Returns the point removed.
makeEmpty: Purges all points from an R-priority queue.
Note that the header file group.h defines the type RPriorityQueue and provides a macro RPQ_SIZE returning the size of an R-priority queue and a macro RPQ_CLEAR making an R-priority queue empty.
Internally, the points of the R-priority queue are sorted in
descending order. */
/* The function initFromPartnStack initializes an existing R-priority queue to the points in a given cell of the top partition on a given partition
stack. */
void initFromPartnStack(
RPriorityQueue *rpq, /* R-priority queue to initialize. */
PartitionStack *PiStack, /* The partition stack. */ Unsigned cellNumber, /* The R-priority queue is initialized to cell
cellNumber of top partition on bfPiStack */ const RBase *const AAA) /* Only omega and invOmega are needed. */
{ Unsigned i, j, p, a, b, k, m, t, left, right, mid, splitKey, bound, tRank,
splitKeyRank, final;
UnsignedS qSortStack[20][2]; Unsigned qSortTop = 0;
UnsignedS *const omega = AAA->omega, *const invOmega = AAA->invOmega; char *temp;
/* Check that r-priority queue has required size (for debugging). */ /* assert( PiStack->cellSize[cellNumber] == rpq->maxSize); */
/* Copy the appropriate cell of the partition stack to the R-priority
queue. */
i = 0; for ( j = PiStack->startCell[cellNumber] , bound = j +
PiStack->cellSize[cellNumber] ; j < bound ; ++j )
rpq->pointList[++i] = PiStack->pointList[j];
rpq->size = i;
/* Sort the R-priority queue in descending order. The following strategy is used: If the size is <= 10, straight insertion sort is used. Otherwise, if the size is >= degree/10, an array of flags is used. Otherwise, quicksort is used, with sublists of size <= 10
being handled by straight insertion sort. */
/* If the size is <= 10, sort directly by straight insertion sort and
return. */ if ( rpq->size <= 10 ) {
rpq->pointList[0] = 0;
invOmega[0] = rpq->degree+1; for ( m = 2 ; m <= rpq->size ; ++m) {
t = rpq->pointList[m];
tRank = invOmega[t];
k = m - 1; while ( invOmega[rpq->pointList[k]] < tRank ) {
rpq->pointList[k+1] = rpq->pointList[k];
--k;
}
rpq->pointList[k+1] = t;
} return;
}
/* Otherwise, if the size is at least 1/10 the degree, we sort using an
index into a Boolean array. */ if ( rpq->size >= rpq->degree / 10 ) {
temp = allocBooleanArrayDegree(); for ( m = 1 ; m <= rpq->degree ; ++m )
temp[m] = FALSE; for ( m = 1 ; m <= rpq->size ; ++m )
temp[invOmega[rpq->pointList[m]]] = TRUE;
p = 1; for ( m = rpq->degree ; m >= 1 ; --m ) if ( temp[m] )
rpq->pointList[p++] = omega[m];
freeBooleanArrayDegree( temp); return;
}
/* In the remaining case, we partially sort using quicksort. Sublists of size <= qSortCutOff are left unsorted. A final pass with straight
insertion sort completes the sort. */
rpq->pointList[0] = 0;
invOmega[0] = rpq->degree+1; if ( rpq->size > qSortCutOff ) {
rpq->pointList[rpq->size+1] = rpq->degree + 1;
invOmega[rpq->degree+1] = 0;
RPQ_PUSH( 1, rpq->size);
} while ( qSortTop >= 1 ) {
RPQ_POP( a, b); while ( b - a >= qSortCutOff ) {
left = a; right = b + 1; mid = (a + b) / 2;
splitKey = rpq->pointList[mid];
splitKeyRank = invOmega[splitKey];
EXCHANGE( rpq->pointList[left], rpq->pointList[mid], t) do { while ( invOmega[rpq->pointList[++left]] > splitKeyRank )
; while ( invOmega[rpq->pointList[--right]] < splitKeyRank )
; if ( left < right )
EXCHANGE( rpq->pointList[left], rpq->pointList[right], t)
} while ( left < right );
final = right;
EXCHANGE( rpq->pointList[a], rpq->pointList[final], t) if ( final - a >= b - final ) if ( b - final >= qSortCutOff ) {
RPQ_PUSH( a, final-1);
a = final + 1;
} else
b = final - 1; else if ( final - a >= qSortCutOff ) {
RPQ_PUSH( final+1, b);
b = final - 1;
} else
a = final + 1;
}
}
/* Now finish with straight insertion sort. */ for ( m = 2 ; m <= rpq->size ; ++m) {
t = rpq->pointList[m];
tRank = invOmega[t];
k = m - 1; while ( invOmega[rpq->pointList[k]] < tRank ) {
rpq->pointList[k+1] = rpq->pointList[k];
--k;
}
rpq->pointList[k+1] = t;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.