From 707ab1eb815bfb80b804e1a625b76d8e9540731a Mon Sep 17 00:00:00 2001 From: Richard Thier Date: Tue, 6 May 2025 03:06:37 +0200 Subject: [PATCH] neoqs, meanqs and various quicksort variants --- qs.c | 81 ------------------------------ ypsu.cpp | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 135 insertions(+), 93 deletions(-) delete mode 100644 qs.c diff --git a/qs.c b/qs.c deleted file mode 100644 index 6c4bc44..0000000 --- a/qs.c +++ /dev/null @@ -1,81 +0,0 @@ -// gcc qs.c -o qs && ./qs -// Quick sort in C - -#include - -// function to swap elements -void swap(int *a, int *b) { - int t = *a; - *a = *b; - *b = t; -} - -// function to find the partition position -int partition(int array[], int low, int high) { - - // select the rightmost element as pivot - int pivot = array[high]; - - // pointer for greater element - int i = (low - 1); - - // traverse each element of the array - // compare them with the pivot - for (int j = low; j < high; j++) { - if (array[j] <= pivot) { - - // if element smaller than pivot is found - // swap it with the greater element pointed by i - i++; - - // swap element at i with element at j - swap(&array[i], &array[j]); - } - } - - // swap the pivot element with the greater element at i - swap(&array[i + 1], &array[high]); - - // return the partition point - return (i + 1); -} - -void quickSort(int array[], int low, int high) { - if (low < high) { - - // find the pivot element such that - // elements smaller than pivot are on left of pivot - // elements greater than pivot are on right of pivot - int pi = partition(array, low, high); - - // recursive call on the left of pivot - quickSort(array, low, pi - 1); - - // recursive call on the right of pivot - quickSort(array, pi + 1, high); - } -} - -// function to print array elements -void printArray(int array[], int size) { - for (int i = 0; i < size; ++i) { - printf("%d ", array[i]); - } - printf("\n"); -} - -// main function -int main() { - int data[] = {8, 7, 2, 1, 0, 9, 6}; - - int n = sizeof(data) / sizeof(data[0]); - - printf("Unsorted Array\n"); - printArray(data, n); - - // perform quicksort on data - quickSort(data, 0, n - 1); - - printf("Sorted array in ascending order: \n"); - printArray(data, n); -} diff --git a/ypsu.cpp b/ypsu.cpp index 62c4bcf..a1fd6f2 100644 --- a/ypsu.cpp +++ b/ypsu.cpp @@ -16,6 +16,9 @@ #include "ska_sort.hpp" #include "gptsort.h" #include "thiersort.h" +#include "qsort/qsort.h" +#include "qsort/zssort.h" +#include "qsort/chatgpt_qs.h" // #define MAGYAR_SORT_DEFAULT_REUSE #include "magyarsort.h" @@ -41,8 +44,8 @@ std::vector inputtypes = { "ascdesc", "descasc", "descdesc", - "rand", "smallrange", + "rand", }; std::vector geninput(const std::string &type, int n) { std::vector v(n); @@ -121,7 +124,80 @@ void twopass(uint32_t *a, int n) { free(buf); } -// TODO: zssort (quicksort jobbítás) +/** "Standardly" written inplace recursive quicksort */ +static inline void do_qsort(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + quicksort(a, 0, n - 1); +} + +static inline void do_qsr3(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + quicksort_rand3(a, 0, n - 1, &state); +} + + +/** Quicksort with fast random pivoting */ +static inline void do_qsr(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + quicksort_rand(a, 0, n - 1, &state); +} + +/** Zsolti's quicksort version with at most O(log(n)) memuse because loop instead half of the recursions */ +static inline void do_zsssort(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + zssort(a, 0, n - 1); +} + +/** Fastrandomized zss */ +static inline void do_zsr(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + zssort_rand(a, 0, n - 1, &state); +} + +/** Fastrandomized zss3 */ +static inline void do_zsr3(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + zssort_rand3(a, 0, n - 1, &state); +} + +/** Fastrandomized zss3 single-pass threewayed */ +static inline void do_zsr3_sp(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + zssort_rand3_sp(a, 0, n - 1, &state); +} + +/** Fastrandomized zss3 single-pass threewayed */ +static inline void do_zsr3_sp2(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + zssort_rand3_sp2(a, 0, n - 1, &state); +} + +/** Fastrandomized zss with const input check */ +static inline void do_zsrc(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + zsrc(a, 0, n - 1, &state); +} + +/** meanqs */ +static inline void do_meanqs(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + meanqs(a, 0, n - 1, &state); +} + +/** neoqs */ +static inline void do_neoqs(uint32_t *a, int n) noexcept { + assert(n * uint32_t(sizeof(a[0])) <= INT_MAX); + rpivotstate state; + neoqs(a, 0, n - 1, &state); +} // mormord — Today at 2:27 AM // 1 2 2 2 3 @@ -287,7 +363,7 @@ static inline void mormord_sort_impl(uint32_t *a, int n) noexcept { /* Pivot 2 */ uint32_t radixval2 = morgrab(a[pivoti2]); - uint32_t targeti2 = --radics2[radixval2]; // dec index (!) + uint32_t targeti2 = boundz.second + (--radics2[radixval2]); // dec index (!) // Bitmask: true -> 11.....1; false -> 00.....0 uint32_t mask2 = ~((targeti2 > pivoti2) - 1); @@ -327,7 +403,7 @@ static inline void mormord_sort_impl(uint32_t *a, int n) noexcept { /* Pivot 2+ */ uint32_t radixval2 = morgrab(a[pivoti2]); - uint32_t targeti2 = --radics2[radixval2]; // dec index (!) + uint32_t targeti2 = boundz.second + (--radics2[radixval2]); // dec index (!) // Bitmask: true -> 11.....1; false -> 00.....0 uint32_t mask2 = ~((targeti2 > pivoti2) - 1); @@ -764,12 +840,14 @@ void measure_single(int n) { int main(void) { //int n = 100000000; //int n = 10000000; - //int n = 1000000; + int n = 1000000; //int n = 100000; - //int n = 10000; + //int n = 20000; //int n = 1000; - int n = 200; + //int n = 200; + //int n = 170; //int n = 100; + //int n = 180; //int n = 10; printf("Sorting %d elements:\n\n", n); @@ -780,15 +858,18 @@ int main(void) { for (auto inputtype : inputtypes) { printf("%10s", inputtype.c_str()); - // fflush(stdout); // XXX: FIXME? + // fflush(stdout); std::vector v(n), w(n), expected(n); v = geninput(inputtype, n); measure(inputtype, "copy", [&] { w = v; }); w = v; measure(inputtype, "std", [&] { std::sort(std::begin(w), std::end(w)); }); expected = w; + + /* w = v; measure(inputtype, "ska", [&] { ska_sort(std::begin(w), std::end(w)); }); + */ w = v; measure(inputtype, "ska_copy", [&] { std::vector buf(w.size()); @@ -796,15 +877,16 @@ int main(void) { w.swap(buf); } }); - /* + /* w = v; measure(inputtype, "magyar", [&] { MagyarSort::sort(&w[0], w.size()); }); assert(w == expected); - */ + */ + + /* w = v; measure(inputtype, "mormord", [&] { mormord_sort(&w[0], w.size()); }); assert(w == expected); - /* w = v; measure(inputtype, "2pass", [&] { twopass(&w[0], w.size()); }); @@ -823,10 +905,51 @@ int main(void) { assert(w == expected); w = v; measure(inputtype, "sp", [&] { spsort(&w[0], w.size()); }); - assert(w == expected);*/ + assert(w == expected); w = v; measure(inputtype, "gptbuck", [&] { gpt_bucket_sort(&w[0], w.size()); }); assert(w == expected); + w = v; + measure(inputtype, "gpt_qsort", [&] { gpt_quicksort(w); }); + assert(w == expected); + w = v; + measure(inputtype, "qsort", [&] { do_qsort(&w[0], w.size()); }); + assert(w == expected); + w = v; + measure(inputtype, "zssort", [&] { do_zsssort(&w[0], w.size()); }); + assert(w == expected); + w = v; + measure(inputtype, "qsr", [&] { do_qsr(&w[0], w.size()); }); + assert(w == expected); + w = v; + measure(inputtype, "zsr", [&] { do_zsr(&w[0], w.size()); }); + assert(w == expected); + */ + w = v; + measure(inputtype, "qsr3", [&] { do_qsr3(&w[0], w.size()); }); + assert(w == expected); + w = v; + measure(inputtype, "zsr3", [&] { do_zsr3(&w[0], w.size()); }); + assert(w == expected); + w = v; + measure(inputtype, "zsr3_sp", [&] { do_zsr3_sp(&w[0], w.size()); }); + assert(w == expected); + w = v; + measure(inputtype, "zsr3_sp2", [&] { do_zsr3_sp2(&w[0], w.size()); }); + assert(w == expected); + /* + w = v; + measure(inputtype, "zsrc", [&] { do_zsrc(&w[0], w.size()); }); + assert(w == expected); + */ + w = v; + measure(inputtype, "meanqs", [&] { do_meanqs(&w[0], w.size()); }); + assert(w == expected); + + w = v; + measure(inputtype, "neoqs", [&] { do_neoqs(&w[0], w.size()); }); + assert(w == expected); + /* w = v; measure(inputtype, "magbuck", [&] { magyar_bucket_sort(&w[0], w.size()); });