switched from size_t to uint32; using custom swap; packed recursive call into getMedian function with reference param to not copy each iteration

This commit is contained in:
incredibleLeitman 2020-10-17 00:29:45 +02:00
parent 39e0f637a0
commit 1e2abe1341

View File

@ -3,12 +3,12 @@
#include <vector> #include <vector>
// Lomuto Partitioning // Lomuto Partitioning
int randomizedPartition(std::vector<size_t>& values, int p, int r) int randomizedPartition(std::vector<uint32_t>& values, int p, int r)
{ {
int i = p + rand() % (r - p); // generate a random number in {p, ..., r} int i = p + rand() % (r - p); // generate a random number in {p, ..., r}
swap(&values[i], &values[r]); swap(&values[i], &values[r]);
int pivotValue = values[r]; uint32_t pivotValue = values[r];
i = p - 1; i = p - 1;
for (int j = p; j < r; j++) for (int j = p; j < r; j++)
{ {
@ -24,12 +24,12 @@ int randomizedPartition(std::vector<size_t>& values, int p, int r)
// TODO: Hoare Partitioning // TODO: Hoare Partitioning
// https://www.geeksforgeeks.org/quicksort-using-random-pivoting/ // https://www.geeksforgeeks.org/quicksort-using-random-pivoting/
int randomizedPartition2(std::vector<size_t>& values, int low, int high) int randomizedPartition2(std::vector<uint32_t>& values, int low, int high)
{ {
int i = low + rand() % (high - low); // generate a random number in {p, ..., r} int i = low + rand() % (high - low); // generate a random number in {p, ..., r}
std::swap(values[i], values[low]); swap(&values[i], &values[low]);
int pivot = values[low]; uint32_t pivotValue = values[low];
i = low - 1; i = low - 1;
int j = high + 1; int j = high + 1;
while (true) { while (true) {
@ -37,42 +37,42 @@ int randomizedPartition2(std::vector<size_t>& values, int low, int high)
// or equal to pivot // or equal to pivot
do { do {
i++; i++;
} while (values[i] < pivot); } while (values[i] < pivotValue);
// Find rightmost element smaller than // Find rightmost element smaller than
// or equal to pivot // or equal to pivot
do { do {
j--; j--;
} while (values[j] > pivot); } while (values[j] > pivotValue);
// If two pointers met // If two pointers met
if (i >= j) if (i >= j)
return j; return j;
std::swap(values[i], values[j]); swap(&values[i], &values[j]);
} }
} }
int randomizedPartition3(std::vector<size_t>& values, int l, int r) int randomizedPartition3(std::vector<uint32_t>& values, int l, int r)
{ {
int n = r - l + 1; int i = rand() % (r - l + 1);
int pivot = rand() % n; swap(&values[l + i], &values[r]);
std::swap(values[l + pivot], values[r]);
int x = values[r], i = l; uint32_t pivotValue = values[r];
i = l;
for (int j = l; j <= r - 1; j++) for (int j = l; j <= r - 1; j++)
{ {
if (values[j] <= x) if (values[j] <= pivotValue)
{ {
std::swap(values[i], values[j]); swap(&values[i], &values[j]);
i++; i++;
} }
} }
std::swap(values[i], values[r]); swap(&values[i], &values[r]);
return i; return i;
} }
int randomizedSelect(std::vector<size_t> values, int p, int r, int i) uint32_t randomizedSelect(std::vector<uint32_t>& values, int p, int r, int i)
{ {
/* /*
// Partition the array around a random element and // Partition the array around a random element and
@ -104,12 +104,17 @@ int randomizedSelect(std::vector<size_t> values, int p, int r, int i)
if (p == r) return values[p]; if (p == r) return values[p];
//int q = randomizedPartition(values, p, r); // Pivot Element A[q] int q = randomizedPartition(values, p, r); // Pivot Element A[q]
//int q = randomizedPartition2(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 = 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 values[q]; // Pivot ist das gesuchte
else if (i < k) else if (i < k)
return randomizedSelect(values, p, q - 1, i); return randomizedSelect(values, p, q - 1, i);
else return randomizedSelect(values, q + 1, r, i - k); else return randomizedSelect(values, q + 1, r, i - k);
} }
uint32_t getRandomizedSelectMedian(std::vector<uint32_t> values, int p, int r, int i)
{
return randomizedSelect(values, p, r, i);
}