diff --git a/MedianQuicksort.h b/MedianQuicksort.h index d918e7f..f6e9ea6 100644 --- a/MedianQuicksort.h +++ b/MedianQuicksort.h @@ -1,40 +1,26 @@ #pragma once -uint32_t pivotPartition(std::vector& values, uint32_t left, uint32_t right) { - uint32_t pivotIndex = left + (right - left) / 2; - uint32_t pivotValue = values[pivotIndex]; - int i = left; - int j = right; - while (i <= j) { - while (values[i] < pivotValue) - { - i++; - } - while (values[j] > pivotValue) - { - j--; - } - if (i <= j) { - swap(&values[i], &values[j]); - i++; - j--; - } - } - return i; +int pivotPartition(std::vector& a, int p, int r) { + + return partition(a, p, r); } -void quicksort(std::vector& values, uint32_t left, uint32_t right) +void quicksort(std::vector& a, int p, int r) { - if (left < right) { - uint32_t pivotIndex = pivotPartition(values, left, right); - quicksort(values, left, pivotIndex - 1); - quicksort(values, pivotIndex, right); + if (p < r) { + int i = pivotPartition(a, p, r); +#ifdef PARTITION_TYPE_LOMUTO + quicksort(a, p, i - 1); +#elif defined PARTITION_TYPE_HOARE + quicksort(a, p, i); +#endif + quicksort(a, i + 1, r); } } -uint32_t getQuicksortMedian(std::vector values, uint32_t i) +uint32_t getQuicksortMedian(std::vector a, int i) { //std::qsort(numbers); // only takes array param -> custom implementation with vector - quicksort(values, 0, values.size() - 1); - return values[i]; + quicksort(a, 0, a.size() - 1); + return a[i]; } \ No newline at end of file diff --git a/RandomizedSelect.h b/RandomizedSelect.h index 5751b58..e2d4479 100644 --- a/RandomizedSelect.h +++ b/RandomizedSelect.h @@ -1,120 +1,49 @@ #pragma once -#include - -// Lomuto Partitioning -int randomizedPartition(std::vector& values, int p, int r) +int randomizedPartition(std::vector& a, int p, int r) { - int i = p + rand() % (r - p); // generate a random number in {p, ..., r} - swap(&values[i], &values[r]); - - uint32_t pivotValue = values[r]; - i = p - 1; - for (int j = p; j < r; j++) - { - if (values[j] <= pivotValue) - { - i++; - swap(&values[i], &values[j]); - } - } - swap(&values[i + 1], &values[r]); - return (i + 1); + // generate a random number in {p, ..., r} to swap +#ifdef PARTITION_TYPE_LOMUTO + int i = p + rand() % (r - p); + swap(&a[i], &a[r]); +#elif defined PARTITION_TYPE_HOARE + int i = rand() % (r - p + 1); + swap(&a[p + i], &a[r]); +#endif + return partition(a, p, r); } -// TODO: Hoare Partitioning -// https://www.geeksforgeeks.org/quicksort-using-random-pivoting/ -int randomizedPartition2(std::vector& values, int low, int high) +uint32_t randomizedSelect(std::vector& a, int p, int r, int i) { - int i = low + rand() % (high - low); // generate a random number in {p, ..., r} - swap(&values[i], &values[low]); - - uint32_t pivotValue = values[low]; - i = low - 1; - int j = high + 1; - while (true) { - // Find leftmost element greater than - // or equal to pivot - do { - i++; - } while (values[i] < pivotValue); - - // Find rightmost element smaller than - // or equal to pivot - do { - j--; - } while (values[j] > pivotValue); - - // If two pointers met - if (i >= j) - return j; - - swap(&values[i], &values[j]); - } -} - -int randomizedPartition3(std::vector& values, int l, int r) -{ - int i = rand() % (r - l + 1); - swap(&values[l + i], &values[r]); - - uint32_t pivotValue = values[r]; - i = l; - for (int j = l; j <= r - 1; j++) - { - if (values[j] <= pivotValue) - { - swap(&values[i], &values[j]); - i++; - } - } - swap(&values[i], &values[r]); - return i; -} - -uint32_t randomizedSelect(std::vector& values, int p, int r, int i) -{ - /* - // Partition the array around a random element and - // get position of pivot element in sorted array - int pos = randomizedPartition(values, p, r); - - // If position is same as k - if (pos - p == i - 1) - return values[pos]; - if (pos - p > i - 1) // If position is more, recur for left subarray - return randomizedSelect(values, p, pos - 1, i); - - // Else recur for right subarray - return randomizedSelect(values, pos + 1, r, i - pos + p - 1); - */ - + // ----------------------------------------------------------- // Pseudo code Alux Nimmervoll, Algo vo3 // Anmerkung: code funktioniert! - /* - RANDOMIZED-SELECT(A,p,r,i) - if (p==r) then return A[p] - q=RANDOMIZED_PARTITION(A,p,r) //Pivot Element A[q] - k=q-p+1 //Anzahl Elemente A[p..q] - if (i==k) then return A[q] //Pivot ist das gesuchte - elseif (i values, int p, int r, int i) +uint32_t getRandomizedSelectMedian(std::vector a, int p, int r, int i) { - return randomizedSelect(values, p, r, i); + return randomizedSelect(a, p, r, i); } \ No newline at end of file diff --git a/common.h b/common.h index c8959c2..b61a8fd 100644 --- a/common.h +++ b/common.h @@ -1,4 +1,5 @@ #pragma once +#include // custom swap function for just pointer swapping (check difference) void swap(uint32_t* a, uint32_t* b) @@ -20,4 +21,55 @@ int compare(const void* a, const void* b) if (arg1 < arg2) return -1; if (arg1 > arg2) return 1; return 0; -} \ No newline at end of file +} + +#define PARTITION_TYPE_LOMUTO +//#define PARTITION_TYPE_HOARE + +#ifdef PARTITION_TYPE_LOMUTO +// Lomuto Partitioning +int partition(std::vector& a, int p, int r) +{ + uint32_t pivotValue = a[r]; + /*int i = p - 1; + for (int j = p; j < r; j++) + { + if (a[j] <= pivotValue) + { + i++; + swap(&a[i], &a[j]); + } + } + swap(&a[i + 1], &a[r]); + return (i + 1);*/ + int i = p; + for (int j = p; j < r; j++) + { + if (a[j] <= pivotValue) + { + swap(&a[i], &a[j]); + i++; + } + } + swap(&a[i], &a[r]); + return i; +} +#elif defined PARTITION_TYPE_HOARE +// Hoare Partitioning +int partition(std::vector& a, int p, int r) +{ + uint32_t pivotValue = a[p]; + int i = p - 1; + int j = r + 1; + while (true) + { + do { i++; } while (a[i] < pivotValue); + + do { j--; } while (a[j] > pivotValue); + + if (i >= j) return j; + + swap(&a[i], &a[j]); + } +} +#endif \ No newline at end of file