neoqs, meanqs and various quicksort variants
This commit is contained in:
parent
e38a76c0c4
commit
707ab1eb81
81
qs.c
81
qs.c
@ -1,81 +0,0 @@
|
|||||||
// gcc qs.c -o qs && ./qs
|
|
||||||
// Quick sort in C
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
147
ypsu.cpp
147
ypsu.cpp
@ -16,6 +16,9 @@
|
|||||||
#include "ska_sort.hpp"
|
#include "ska_sort.hpp"
|
||||||
#include "gptsort.h"
|
#include "gptsort.h"
|
||||||
#include "thiersort.h"
|
#include "thiersort.h"
|
||||||
|
#include "qsort/qsort.h"
|
||||||
|
#include "qsort/zssort.h"
|
||||||
|
#include "qsort/chatgpt_qs.h"
|
||||||
|
|
||||||
// #define MAGYAR_SORT_DEFAULT_REUSE
|
// #define MAGYAR_SORT_DEFAULT_REUSE
|
||||||
#include "magyarsort.h"
|
#include "magyarsort.h"
|
||||||
@ -41,8 +44,8 @@ std::vector<std::string> inputtypes = {
|
|||||||
"ascdesc",
|
"ascdesc",
|
||||||
"descasc",
|
"descasc",
|
||||||
"descdesc",
|
"descdesc",
|
||||||
"rand",
|
|
||||||
"smallrange",
|
"smallrange",
|
||||||
|
"rand",
|
||||||
};
|
};
|
||||||
std::vector<uint32_t> geninput(const std::string &type, int n) {
|
std::vector<uint32_t> geninput(const std::string &type, int n) {
|
||||||
std::vector<uint32_t> v(n);
|
std::vector<uint32_t> v(n);
|
||||||
@ -121,7 +124,80 @@ void twopass(uint32_t *a, int n) {
|
|||||||
free(buf);
|
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
|
// mormord — Today at 2:27 AM
|
||||||
// 1 2 2 2 3
|
// 1 2 2 2 3
|
||||||
@ -287,7 +363,7 @@ static inline void mormord_sort_impl(uint32_t *a, int n) noexcept {
|
|||||||
/* Pivot 2 */
|
/* Pivot 2 */
|
||||||
|
|
||||||
uint32_t radixval2 = morgrab<j>(a[pivoti2]);
|
uint32_t radixval2 = morgrab<j>(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
|
// Bitmask: true -> 11.....1; false -> 00.....0
|
||||||
uint32_t mask2 = ~((targeti2 > pivoti2) - 1);
|
uint32_t mask2 = ~((targeti2 > pivoti2) - 1);
|
||||||
@ -327,7 +403,7 @@ static inline void mormord_sort_impl(uint32_t *a, int n) noexcept {
|
|||||||
/* Pivot 2+ */
|
/* Pivot 2+ */
|
||||||
|
|
||||||
uint32_t radixval2 = morgrab<j>(a[pivoti2]);
|
uint32_t radixval2 = morgrab<j>(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
|
// Bitmask: true -> 11.....1; false -> 00.....0
|
||||||
uint32_t mask2 = ~((targeti2 > pivoti2) - 1);
|
uint32_t mask2 = ~((targeti2 > pivoti2) - 1);
|
||||||
@ -764,12 +840,14 @@ void measure_single(int n) {
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
//int n = 100000000;
|
//int n = 100000000;
|
||||||
//int n = 10000000;
|
//int n = 10000000;
|
||||||
//int n = 1000000;
|
int n = 1000000;
|
||||||
//int n = 100000;
|
//int n = 100000;
|
||||||
//int n = 10000;
|
//int n = 20000;
|
||||||
//int n = 1000;
|
//int n = 1000;
|
||||||
int n = 200;
|
//int n = 200;
|
||||||
|
//int n = 170;
|
||||||
//int n = 100;
|
//int n = 100;
|
||||||
|
//int n = 180;
|
||||||
//int n = 10;
|
//int n = 10;
|
||||||
|
|
||||||
printf("Sorting %d elements:\n\n", n);
|
printf("Sorting %d elements:\n\n", n);
|
||||||
@ -780,15 +858,18 @@ int main(void) {
|
|||||||
|
|
||||||
for (auto inputtype : inputtypes) {
|
for (auto inputtype : inputtypes) {
|
||||||
printf("%10s", inputtype.c_str());
|
printf("%10s", inputtype.c_str());
|
||||||
// fflush(stdout); // XXX: FIXME?
|
// fflush(stdout);
|
||||||
std::vector<uint32_t> v(n), w(n), expected(n);
|
std::vector<uint32_t> v(n), w(n), expected(n);
|
||||||
v = geninput(inputtype, n);
|
v = geninput(inputtype, n);
|
||||||
measure(inputtype, "copy", [&] { w = v; });
|
measure(inputtype, "copy", [&] { w = v; });
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "std", [&] { std::sort(std::begin(w), std::end(w)); });
|
measure(inputtype, "std", [&] { std::sort(std::begin(w), std::end(w)); });
|
||||||
expected = w;
|
expected = w;
|
||||||
|
|
||||||
|
/*
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "ska", [&] { ska_sort(std::begin(w), std::end(w)); });
|
measure(inputtype, "ska", [&] { ska_sort(std::begin(w), std::end(w)); });
|
||||||
|
*/
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "ska_copy", [&] {
|
measure(inputtype, "ska_copy", [&] {
|
||||||
std::vector<uint32_t> buf(w.size());
|
std::vector<uint32_t> buf(w.size());
|
||||||
@ -796,15 +877,16 @@ int main(void) {
|
|||||||
w.swap(buf);
|
w.swap(buf);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "magyar", [&] { MagyarSort::sort<uint32_t>(&w[0], w.size()); });
|
measure(inputtype, "magyar", [&] { MagyarSort::sort<uint32_t>(&w[0], w.size()); });
|
||||||
assert(w == expected);
|
assert(w == expected);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "mormord", [&] { mormord_sort(&w[0], w.size()); });
|
measure(inputtype, "mormord", [&] { mormord_sort(&w[0], w.size()); });
|
||||||
assert(w == expected);
|
assert(w == expected);
|
||||||
/*
|
|
||||||
|
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "2pass", [&] { twopass(&w[0], w.size()); });
|
measure(inputtype, "2pass", [&] { twopass(&w[0], w.size()); });
|
||||||
@ -823,10 +905,51 @@ int main(void) {
|
|||||||
assert(w == expected);
|
assert(w == expected);
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "sp", [&] { spsort(&w[0], w.size()); });
|
measure(inputtype, "sp", [&] { spsort(&w[0], w.size()); });
|
||||||
assert(w == expected);*/
|
assert(w == expected);
|
||||||
w = v;
|
w = v;
|
||||||
measure(inputtype, "gptbuck", [&] { gpt_bucket_sort(&w[0], w.size()); });
|
measure(inputtype, "gptbuck", [&] { gpt_bucket_sort(&w[0], w.size()); });
|
||||||
assert(w == expected);
|
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;
|
w = v;
|
||||||
measure(inputtype, "magbuck", [&] { magyar_bucket_sort(&w[0], w.size()); });
|
measure(inputtype, "magbuck", [&] { magyar_bucket_sort(&w[0], w.size()); });
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user