moved partition function into common; combined partition magic and fixed randomizedSelect for HoarePartitioning
This commit is contained in:
parent
5ac57571eb
commit
0cfd9e66ec
@ -1,40 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
uint32_t pivotPartition(std::vector<uint32_t>& 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<uint32_t>& a, int p, int r) {
|
||||
|
||||
return partition(a, p, r);
|
||||
}
|
||||
|
||||
void quicksort(std::vector<uint32_t>& values, uint32_t left, uint32_t right)
|
||||
void quicksort(std::vector<uint32_t>& 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<uint32_t> values, uint32_t i)
|
||||
uint32_t getQuicksortMedian(std::vector<uint32_t> 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];
|
||||
}
|
@ -1,120 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Lomuto Partitioning
|
||||
int randomizedPartition(std::vector<uint32_t>& values, int p, int r)
|
||||
int randomizedPartition(std::vector<uint32_t>& 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<uint32_t>& values, int low, int high)
|
||||
uint32_t randomizedSelect(std::vector<uint32_t>& 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<uint32_t>& 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<uint32_t>& 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<k)
|
||||
then return RANDOMIZED-SELECT(A,p,q-1,i)
|
||||
else return RANDOMIZED-SELECT(A,q+1,r,i-k)
|
||||
*/
|
||||
//
|
||||
// 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<k)
|
||||
// then return RANDOMIZED-SELECT(A,p,q-1,i)
|
||||
// else return RANDOMIZED-SELECT(A,q+1,r,i-k)
|
||||
// -----------------------------------------------------------
|
||||
|
||||
if (p == r) return values[p];
|
||||
if (p == r) return a[p];
|
||||
|
||||
int q = randomizedPartition(values, p, r); // Pivot Element A[q]
|
||||
//int q = randomizedPartition2(values, p, r); // Pivot Element A[q]
|
||||
//int q = randomizedPartition3(values, p, r); // Pivot Element A[q]
|
||||
int q = randomizedPartition(a, p, r); // Pivot Element A[q]
|
||||
int k = q - p + 1; // Anzahl Elemente A[p..q]
|
||||
if (i == k) return values[q]; // Pivot ist das gesuchte
|
||||
if (i == k) return a[q]; // Pivot ist das gesuchte
|
||||
else if (i < k)
|
||||
return randomizedSelect(values, p, q - 1, i);
|
||||
else return randomizedSelect(values, q + 1, r, i - k);
|
||||
#ifdef PARTITION_TYPE_LOMUTO
|
||||
return randomizedSelect(a, p, q - 1, i);
|
||||
#elif defined PARTITION_TYPE_HOARE
|
||||
return randomizedSelect(a, p, q, i);
|
||||
#endif
|
||||
else return randomizedSelect(a, q + 1, r, i - k);
|
||||
}
|
||||
|
||||
uint32_t getRandomizedSelectMedian(std::vector<uint32_t> values, int p, int r, int i)
|
||||
uint32_t getRandomizedSelectMedian(std::vector<uint32_t> a, int p, int r, int i)
|
||||
{
|
||||
return randomizedSelect(values, p, r, i);
|
||||
return randomizedSelect(a, p, r, i);
|
||||
}
|
54
common.h
54
common.h
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
#define PARTITION_TYPE_LOMUTO
|
||||
//#define PARTITION_TYPE_HOARE
|
||||
|
||||
#ifdef PARTITION_TYPE_LOMUTO
|
||||
// Lomuto Partitioning
|
||||
int partition(std::vector<uint32_t>& 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<uint32_t>& 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
|
Loading…
x
Reference in New Issue
Block a user