apply and prepare operations - first version
This commit is contained in:
parent
8784773800
commit
8dd103ca54
94
thiersort.h
94
thiersort.h
@ -364,28 +364,6 @@ static inline void thiersort8_floatkey(
|
||||
TSTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create [key, index] pairs from your raw input data sequence. O(n) runtime.
|
||||
*
|
||||
* Useful if you have an seq/arr of elements to sort and what them prepared to be
|
||||
* properly thiersorted as key, index pairs. Then you can apply that reordering
|
||||
* later using thiersort_apply(..). Also useful for online data stream sources.
|
||||
*
|
||||
* BEWARE: The returned array must be freed by you - with a corresponding free.
|
||||
* An alternative is to do a thiersort_apply(..) call (for the array case).
|
||||
*
|
||||
* @param askey The sequence that generates input. Gives the ith elem as key.
|
||||
* @param length The length of input sequence.
|
||||
* @param malloc The function to use for allocating the key-index array.
|
||||
* @returns The array of keys and indices for that key to sort.
|
||||
*/
|
||||
static inline struct tselem *thiersort_prepare(
|
||||
union tskey (askey)(TSU32 i),
|
||||
TSU32 length,
|
||||
void* (*malloc)(size_t size)) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Create [key, index] pairs from your raw input data array. O(n) runtime.
|
||||
*
|
||||
@ -396,30 +374,82 @@ static inline struct tselem *thiersort_prepare(
|
||||
* BEWARE: The returned array must be freed by you - with a corresponding free.
|
||||
* An alternative is to do a thiersort_apply(..) call (for the array case).
|
||||
*
|
||||
* @param arr The input array.
|
||||
* @param askey The sequence that generates input. Gives the ith elem as key.
|
||||
* @param length The length of input sequence.
|
||||
* @param elemlen The size of a single elem,
|
||||
* @param length The length of input sequence. Number of elements.
|
||||
* @param malloc The function to use for allocating the key-index array.
|
||||
* @returns The array of keys and indices for that key to sort.
|
||||
* @returns Created array of keys+indices for that key to sort.
|
||||
*/
|
||||
static inline struct tselem *thiersort_prepare_array(
|
||||
void *arr,
|
||||
union tskey (askey)(void *elem),
|
||||
TSU32 length,
|
||||
TSU32 elemlen,
|
||||
TSU32 length,
|
||||
void* (*malloc)(size_t size)) {
|
||||
// TODO
|
||||
/* Allocate */
|
||||
tselem *out = malloc(length * sizeof(tselem));
|
||||
|
||||
/* Fill */
|
||||
TSU32 j = 0;
|
||||
for(size_t i = 0; i < (length * elemlen); i += elemlen, ++j) {
|
||||
out[j].key = askey((void *)((TSU8 *)arr + i));
|
||||
out[j].i = j;
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the given [key,index] sort result back to an array.
|
||||
*
|
||||
* Rem.: Also frees the sort result array!
|
||||
*
|
||||
* @param sortres A thiersort result on previously prepared arr.
|
||||
* @param arr The original array which was prepared for sort and was sorted.
|
||||
* @param length The number of element (both in sortres and arr)
|
||||
* @param elemlen Size of a single element
|
||||
* @param tmp An array of elemlen bytes to store values for swap!
|
||||
* @param free The operation used for freeing the sort res array.
|
||||
*/
|
||||
static inline void thiersort_apply(
|
||||
struct tselem *sortres,
|
||||
void *arr,
|
||||
TSU32 length,
|
||||
TSU32 elemlen,
|
||||
void (*free)(void *ptr)) {
|
||||
// TODO
|
||||
struct tselem *sortres,
|
||||
void *arr,
|
||||
TSU32 length,
|
||||
TSU32 elemsize,
|
||||
void *tmp,
|
||||
void (*free)(void *ptr)) {
|
||||
// Replace all positions
|
||||
for(TSU32 i = 0; i < length; ++i) {
|
||||
// Replace the whole chain starting at i (j for chain index)
|
||||
// This works because we can easily check what does'nt need moves anymore.
|
||||
TSU32 j = i;
|
||||
TSU32 ni = sortres[j].i;
|
||||
|
||||
// Until would move to its own position, chain
|
||||
// This also solves "already at right place" originals.
|
||||
while(ni != j) {
|
||||
// xchg j and ni
|
||||
memcpy(tmp, arr[(size_t)j * elemsize], elemsize);
|
||||
memcpy(
|
||||
arr[(size_t)j * elemsize],
|
||||
arr[(size_t)ni * elemsize],
|
||||
elemsize);
|
||||
memcpy(arr[(size_t)ni * elemsize], tmp, elemsize);
|
||||
|
||||
// Mark j index as done in sortres for outer loop.
|
||||
// This is necessary for inner loop stopping early
|
||||
// and outer catch up on already processed location.
|
||||
sortres[j].i = j;
|
||||
|
||||
// Update j and ni
|
||||
// Now we must find what should be at new location j
|
||||
// instead of what we swap in there from old j loc.
|
||||
TSU32 j = ni;
|
||||
TSU32 ni = sortres[j].i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user