schwab: fixed endless run, bug in hi not bigger then mid and lo because only indices are checked lol

This commit is contained in:
Richard Thier 2025-05-08 22:47:52 +02:00
parent 5775e6c201
commit 6d8802f479
2 changed files with 24 additions and 9 deletions

View File

@ -1,4 +1,6 @@
int data[] = { 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, 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, 8, 7, 2, 1, 0, 9, 6,*/
8, 7, 2, 1, 0, 9, 6,
8, 7, 2, 1, 0, 9, 6,
}; };

View File

@ -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] * Expects: arr[plo] <= arr[pmid] <= arr[phi]
* Results: arr[low..plo - 1] <= arr[plo..pmid - 1] <= arr[pmid..phi - 1] <= arr[phi.. high] * 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 arr The array to partition
* @param low Inclusive smallest index. * @param low Inclusive smallest index.
* @param high Inclusive highest index. * @param high Inclusive highest index.
@ -50,15 +53,20 @@ static inline void schwab_partition(
int *pmid, int *pmid,
int *phi) { int *phi) {
/* Grab pivot values (keys of partitioning) */ /* [*] Swapping arr[phi]<->arr[high] ensures stop condition later */
uint32_t klo = arr[*plo]; uint32_t tmphi = arr[*phi];
uint32_t kmid = arr[*pmid]; arr[*phi] = arr[high];
uint32_t khi = arr[*phi]; arr[high] = tmphi;
/* Aren't inclusive end indices of 4 "blocks" - b0 is smallest vals */ /* Aren't inclusive end indices of 4 "blocks" - b0 is smallest vals */
int b0 = low, b1 = low, b2 = low, b3 = low; 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 */ /* This I moved to be first for hot code path for constant / smallrange */
if(arr[b3] >= khi) { if(arr[b3] >= khi) {
++b3; ++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 */ /* Handle output vars as per doc comment */
*plo = b0; *plo = b0;
*pmid = b1; *pmid = b1;
*phi = b2; *phi = b2; /* Because of: [*] */
} }
/** Always at most log(n) space needing 4-way quicksort-like alg */ /** Always at most log(n) space needing 4-way quicksort-like alg */