From 6d8802f47904dc0f4aca09e2ee7872cd9077e0ba Mon Sep 17 00:00:00 2001 From: Richard Thier Date: Thu, 8 May 2025 22:47:52 +0200 Subject: [PATCH] schwab: fixed endless run, bug in hi not bigger then mid and lo because only indices are checked lol --- data.inc | 6 +++--- schwab_sort.h | 27 +++++++++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/data.inc b/data.inc index f93cf8b..895633f 100644 --- a/data.inc +++ b/data.inc @@ -1,4 +1,6 @@ int data[] = { + 8, 7, 2, 1, 0, 9, 6,1 + /*8, 7, 2, 1, 0, 9, 6, 8, 7, 2, 1, 0, 9, 6, 8, 7, 2, 1, 0, 9, 6, 8, 7, 2, 1, 0, 9, 6, @@ -7,7 +9,5 @@ int data[] = { 8, 7, 2, 1, 0, 9, 6, 8, 7, 2, 1, 0, 9, 6, 8, 7, 2, 1, 0, 9, 6, - 8, 7, 2, 1, 0, 9, 6, - 8, 7, 2, 1, 0, 9, 6, - 8, 7, 2, 1, 0, 9, 6, + 8, 7, 2, 1, 0, 9, 6,*/ }; diff --git a/schwab_sort.h b/schwab_sort.h index 0142286..81e069a 100644 --- a/schwab_sort.h +++ b/schwab_sort.h @@ -35,6 +35,9 @@ static inline uint32_t schwab_pick_pivot(sch_rand_state *state, uint32_t len) { * Expects: arr[plo] <= arr[pmid] <= arr[phi] * Results: arr[low..plo - 1] <= arr[plo..pmid - 1] <= arr[pmid..phi - 1] <= arr[phi.. high] * + * Also: Adding together lengths of all results arrays shrinks by 1 compared to start arr. + * This means that we ensure recursions / loops always end in quicksort... + * * @param arr The array to partition * @param low Inclusive smallest index. * @param high Inclusive highest index. @@ -50,15 +53,20 @@ static inline void schwab_partition( int *pmid, int *phi) { - /* Grab pivot values (keys of partitioning) */ - uint32_t klo = arr[*plo]; - uint32_t kmid = arr[*pmid]; - uint32_t khi = arr[*phi]; + /* [*] Swapping arr[phi]<->arr[high] ensures stop condition later */ + uint32_t tmphi = arr[*phi]; + arr[*phi] = arr[high]; + arr[high] = tmphi; /* Aren't inclusive end indices of 4 "blocks" - b0 is smallest vals */ int b0 = low, b1 = low, b2 = low, b3 = low; - while(b3 < high + 1) { + /* Keys only - no element copy is made here */ + uint32_t klo = arr[*plo]; + uint32_t kmid = arr[*pmid]; + uint32_t khi = arr[*phi]; + + while(b3 < high) { /* This I moved to be first for hot code path for constant / smallrange */ if(arr[b3] >= khi) { ++b3; @@ -94,10 +102,17 @@ static inline void schwab_partition( } } + /* [*] Swap the chosen pivot to begin of last block */ + /* This way we can return bigger index and by that */ + /* this always removes an element per run at least */ + tmphi = arr[b2]; + arr[b2++] = arr[high]; + arr[high] = tmphi; + /* Handle output vars as per doc comment */ *plo = b0; *pmid = b1; - *phi = b2; + *phi = b2; /* Because of: [*] */ } /** Always at most log(n) space needing 4-way quicksort-like alg */