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
|
#pragma once
|
||||||
|
|
||||||
uint32_t pivotPartition(std::vector<uint32_t>& values, uint32_t left, uint32_t right) {
|
int pivotPartition(std::vector<uint32_t>& a, int p, int r) {
|
||||||
uint32_t pivotIndex = left + (right - left) / 2;
|
|
||||||
uint32_t pivotValue = values[pivotIndex];
|
return partition(a, p, r);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
if (p < r) {
|
||||||
uint32_t pivotIndex = pivotPartition(values, left, right);
|
int i = pivotPartition(a, p, r);
|
||||||
quicksort(values, left, pivotIndex - 1);
|
#ifdef PARTITION_TYPE_LOMUTO
|
||||||
quicksort(values, pivotIndex, right);
|
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
|
//std::qsort(numbers); // only takes array param -> custom implementation with vector
|
||||||
quicksort(values, 0, values.size() - 1);
|
quicksort(a, 0, a.size() - 1);
|
||||||
return values[i];
|
return a[i];
|
||||||
}
|
}
|
@ -1,120 +1,49 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
int randomizedPartition(std::vector<uint32_t>& a, int p, int r)
|
||||||
|
|
||||||
// Lomuto Partitioning
|
|
||||||
int randomizedPartition(std::vector<uint32_t>& values, int p, int r)
|
|
||||||
{
|
{
|
||||||
int i = p + rand() % (r - p); // generate a random number in {p, ..., r}
|
// generate a random number in {p, ..., r} to swap
|
||||||
swap(&values[i], &values[r]);
|
#ifdef PARTITION_TYPE_LOMUTO
|
||||||
|
int i = p + rand() % (r - p);
|
||||||
uint32_t pivotValue = values[r];
|
swap(&a[i], &a[r]);
|
||||||
i = p - 1;
|
#elif defined PARTITION_TYPE_HOARE
|
||||||
for (int j = p; j < r; j++)
|
int i = rand() % (r - p + 1);
|
||||||
{
|
swap(&a[p + i], &a[r]);
|
||||||
if (values[j] <= pivotValue)
|
#endif
|
||||||
{
|
return partition(a, p, r);
|
||||||
i++;
|
|
||||||
swap(&values[i], &values[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
swap(&values[i + 1], &values[r]);
|
|
||||||
return (i + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Hoare Partitioning
|
uint32_t randomizedSelect(std::vector<uint32_t>& a, int p, int r, int i)
|
||||||
// https://www.geeksforgeeks.org/quicksort-using-random-pivoting/
|
|
||||||
int randomizedPartition2(std::vector<uint32_t>& values, int low, int high)
|
|
||||||
{
|
{
|
||||||
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
|
// Pseudo code Alux Nimmervoll, Algo vo3
|
||||||
// Anmerkung: code funktioniert!
|
// Anmerkung: code funktioniert!
|
||||||
/*
|
//
|
||||||
RANDOMIZED-SELECT(A,p,r,i)
|
// RANDOMIZED-SELECT(A,p,r,i)
|
||||||
if (p==r) then return A[p]
|
// if (p==r) then return A[p]
|
||||||
q=RANDOMIZED_PARTITION(A,p,r) //Pivot Element A[q]
|
// q=RANDOMIZED_PARTITION(A,p,r) //Pivot Element A[q]
|
||||||
k=q-p+1 //Anzahl Elemente A[p..q]
|
// k=q-p+1 //Anzahl Elemente A[p..q]
|
||||||
if (i==k) then return A[q] //Pivot ist das gesuchte
|
// if (i==k) then return A[q] //Pivot ist das gesuchte
|
||||||
elseif (i<k)
|
// elseif (i<k)
|
||||||
then return RANDOMIZED-SELECT(A,p,q-1,i)
|
// then return RANDOMIZED-SELECT(A,p,q-1,i)
|
||||||
else return RANDOMIZED-SELECT(A,q+1,r,i-k)
|
// 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 = randomizedPartition(a, 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 k = q - p + 1; // Anzahl Elemente A[p..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)
|
else if (i < k)
|
||||||
return randomizedSelect(values, p, q - 1, i);
|
#ifdef PARTITION_TYPE_LOMUTO
|
||||||
else return randomizedSelect(values, q + 1, r, i - k);
|
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
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// custom swap function for just pointer swapping (check difference)
|
// custom swap function for just pointer swapping (check difference)
|
||||||
void swap(uint32_t* a, uint32_t* b)
|
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;
|
||||||
if (arg1 > arg2) return 1;
|
if (arg1 > arg2) return 1;
|
||||||
return 0;
|
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