added implementation for median of medians and randomized select
This commit is contained in:
parent
90bb76cb3c
commit
1883659921
@ -1,3 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
// https://en.wikipedia.org/wiki/Median_of_medians
|
||||
// https://en.wikipedia.org/wiki/Median_of_medians
|
||||
int findMedian(std::vector<size_t> values) {
|
||||
size_t median;
|
||||
size_t size = values.size();
|
||||
median = values[(size / 2)];
|
||||
return median;
|
||||
}
|
||||
|
||||
int findMedianOfMedians(std::vector<std::vector<size_t> > values) {
|
||||
std::vector<size_t> medians;
|
||||
for (size_t i = 0; i < values.size(); i++) {
|
||||
size_t m = findMedian(values[i]);
|
||||
medians.push_back(m);
|
||||
}
|
||||
return findMedian(medians);
|
||||
}
|
||||
|
||||
size_t getMedianOfMedians(const std::vector<size_t> values, size_t k) {
|
||||
// Divide the list into n/5 lists of 5 elements each
|
||||
std::vector<std::vector<size_t> > vec2D;
|
||||
size_t count = 0;
|
||||
while (count != values.size()) {
|
||||
size_t countRow = 0;
|
||||
std::vector<size_t> row;
|
||||
while ((countRow < 5) && (count < values.size())) {
|
||||
row.push_back(values[count]);
|
||||
count++;
|
||||
countRow++;
|
||||
}
|
||||
vec2D.push_back(row);
|
||||
}
|
||||
|
||||
// Calculating a new pivot for making splits
|
||||
size_t m = findMedianOfMedians(vec2D);
|
||||
|
||||
// Partition the list into unique elements larger than 'm' (call this sublist L1) and those smaller them 'm' (call this sublist L2)
|
||||
std::vector<size_t> L1, L2;
|
||||
|
||||
for (size_t i = 0; i < vec2D.size(); i++) {
|
||||
for (size_t j = 0; j < vec2D[i].size(); j++) {
|
||||
if (vec2D[i][j] > m) {
|
||||
L1.push_back(vec2D[i][j]);
|
||||
}
|
||||
else if (vec2D[i][j] < m) {
|
||||
L2.push_back(vec2D[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (k <= L1.size()) {
|
||||
return getMedianOfMedians(L1, k);
|
||||
}
|
||||
else if (k > (L1.size() + 1)) {
|
||||
return getMedianOfMedians(L2, k - ((int)L1.size()) - 1);
|
||||
}
|
||||
return m;
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
// Pseudo code Alux Nimmervoll, Algo vo3
|
||||
// Anmerkung: code funktioniert!
|
||||
|
||||
RANDOMIZED-SELECT(A,p,r,i)
|
||||
@ -11,4 +14,32 @@ RANDOMIZED-SELECT(A,p,r,i)
|
||||
elseif (i<k)
|
||||
then return RANDOMIZED-SELECT(A,p,q-1,i)
|
||||
else return RANDOMIZED-SELECT(A,q+1,r,i-k)
|
||||
*/
|
||||
*/
|
||||
|
||||
size_t randomizedPartition(std::vector<size_t>& values, size_t p, size_t r) {
|
||||
size_t i = p + rand() % (r - p + 1); // generate a random number in {p, ..., r}
|
||||
std::swap(values[i], values[r]);
|
||||
|
||||
size_t pivotValue = values[r];
|
||||
i = p - 1;
|
||||
for (size_t j = p; j < r; j++) {
|
||||
if (values[j] <= pivotValue) {
|
||||
i++;
|
||||
std::swap(values[i], values[j]);
|
||||
}
|
||||
}
|
||||
std::swap(values[i + 1], values[r]);
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
size_t randomizedSelect(std::vector<size_t> values, size_t p, size_t r, size_t i)
|
||||
{
|
||||
if (p == r) return values[p];
|
||||
|
||||
size_t q = randomizedPartition(values, p, r); // Pivot Element A[q]
|
||||
size_t k = q - p + 1; // Anzahl Elemente A[p..q]
|
||||
if (i == k) return values[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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user