fixed coding guidelines and added a lot of testcode
This commit is contained in:
parent
fec5e8a6e7
commit
04a25454ac
@ -4,14 +4,16 @@
|
||||
// https://oneraynyday.github.io/algorithms/2016/06/17/Median-Of-Medians/
|
||||
// https://www.geeksforgeeks.org/kth-smallestlargest-element-unsorted-array-set-3-worst-case-linear-time/
|
||||
|
||||
int findMedian(std::vector<size_t> values) {
|
||||
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) {
|
||||
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]);
|
||||
@ -20,14 +22,16 @@ int findMedianOfMedians(std::vector<std::vector<size_t> > values) {
|
||||
return findMedian(medians);
|
||||
}
|
||||
|
||||
size_t getMedianOfMedians(const std::vector<size_t> values, size_t k) {
|
||||
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())) {
|
||||
while ((countRow < 5) && (count < values.size()))
|
||||
{
|
||||
row.push_back(values[count]);
|
||||
count++;
|
||||
countRow++;
|
||||
@ -41,44 +45,41 @@ size_t getMedianOfMedians(const std::vector<size_t> values, size_t k) {
|
||||
// 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) {
|
||||
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) {
|
||||
else if (vec2D[i][j] < m)
|
||||
{
|
||||
L2.push_back(vec2D[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (k <= L1.size()) {
|
||||
if (k <= L1.size())
|
||||
{
|
||||
return getMedianOfMedians(L1, k);
|
||||
}
|
||||
else if (k > (L1.size() + 1)) {
|
||||
else if (k > (L1.size() + 1))
|
||||
{
|
||||
return getMedianOfMedians(L2, k - ((int)L1.size()) - 1);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
// custom swap function
|
||||
void swap(size_t* a, size_t* b)
|
||||
{
|
||||
size_t temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
// A simple function to find median of arr[]. This is called
|
||||
// only for an array of size 5 in this program.
|
||||
// A simple function to find median of arr[].
|
||||
// This is called only for an array of size 5 in this program.
|
||||
int findMedian(size_t arr[], int n)
|
||||
{
|
||||
std::sort(arr, arr + n); // Sort the array
|
||||
return arr[n / 2]; // Return middle element
|
||||
}
|
||||
|
||||
// It searches for x in arr[l..r], and partitions the array
|
||||
// around x.
|
||||
// searches for x in arr[l..r], and partitions the array around x
|
||||
int partition(size_t arr[], int l, int r, int x)
|
||||
{
|
||||
// Search for x in arr[l..r] and move it to end
|
||||
@ -90,12 +91,12 @@ int partition(size_t arr[], int l, int r, int x)
|
||||
|
||||
// Standard partition algorithm
|
||||
i = l;
|
||||
for (int j = l; j <= r - 1; j++)
|
||||
for (int j = l; j < r; j++)
|
||||
{
|
||||
if (arr[j] <= x)
|
||||
{
|
||||
swap(&arr[i], &arr[j]);
|
||||
i++;
|
||||
swap(&arr[i], &arr[j]);
|
||||
}
|
||||
}
|
||||
swap(&arr[i], &arr[r]);
|
||||
|
@ -3,13 +3,15 @@
|
||||
size_t pivotPartition(std::vector<size_t>& values, size_t left, size_t right) {
|
||||
size_t pivotIndex = left + (right - left) / 2;
|
||||
size_t pivotValue = values[pivotIndex];
|
||||
size_t i = left;
|
||||
size_t j = right;
|
||||
int i = left;
|
||||
int j = right;
|
||||
while (i <= j) {
|
||||
while (values[i] < pivotValue) {
|
||||
while (values[i] < pivotValue)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
while (values[j] > pivotValue) {
|
||||
while (values[j] > pivotValue)
|
||||
{
|
||||
j--;
|
||||
}
|
||||
if (i <= j) {
|
||||
@ -21,7 +23,8 @@ size_t pivotPartition(std::vector<size_t>& values, size_t left, size_t right) {
|
||||
return i;
|
||||
}
|
||||
|
||||
void quicksort(std::vector<size_t>& values, size_t left, size_t right) {
|
||||
void quicksort(std::vector<size_t>& values, size_t left, size_t right)
|
||||
{
|
||||
if (left < right) {
|
||||
size_t pivotIndex = pivotPartition(values, left, right);
|
||||
quicksort(values, left, pivotIndex - 1);
|
||||
@ -29,7 +32,8 @@ void quicksort(std::vector<size_t>& values, size_t left, size_t right) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t getQuicksortMedian(std::vector<size_t> values, size_t i) {
|
||||
size_t getQuicksortMedian(std::vector<size_t> values, size_t i)
|
||||
{
|
||||
//std::qsort(numbers); // only takes array param -> custom implementation with vector
|
||||
quicksort(values, 0, values.size() - 1);
|
||||
return values[i];
|
||||
|
@ -2,42 +2,112 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
// Pseudo code Alux Nimmervoll, Algo vo3
|
||||
// Anmerkung: code funktioniert!
|
||||
// Lomuto Partitioning
|
||||
int randomizedPartition(std::vector<size_t>& values, int p, int r)
|
||||
{
|
||||
int i = p + rand() % (r - p); // generate a random number in {p, ..., r}
|
||||
swap(&values[i], &values[r]);
|
||||
|
||||
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)
|
||||
*/
|
||||
|
||||
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];
|
||||
int pivotValue = values[r];
|
||||
i = p - 1;
|
||||
for (size_t j = p; j < r; j++) {
|
||||
if (values[j] <= pivotValue) {
|
||||
for (int j = p; j < r; j++)
|
||||
{
|
||||
if (values[j] <= pivotValue)
|
||||
{
|
||||
i++;
|
||||
std::swap(values[i], values[j]);
|
||||
swap(&values[i], &values[j]);
|
||||
}
|
||||
}
|
||||
std::swap(values[i + 1], values[r]);
|
||||
return i + 1;
|
||||
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)
|
||||
// TODO: Hoare Partitioning
|
||||
// https://www.geeksforgeeks.org/quicksort-using-random-pivoting/
|
||||
int randomizedPartition2(std::vector<size_t>& values, int low, int high)
|
||||
{
|
||||
int i = low + rand() % (high - low); // generate a random number in {p, ..., r}
|
||||
std::swap(values[i], values[low]);
|
||||
|
||||
int pivot = 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] < pivot);
|
||||
|
||||
// Find rightmost element smaller than
|
||||
// or equal to pivot
|
||||
do {
|
||||
j--;
|
||||
} while (values[j] > pivot);
|
||||
|
||||
// If two pointers met
|
||||
if (i >= j)
|
||||
return j;
|
||||
|
||||
std::swap(values[i], values[j]);
|
||||
}
|
||||
}
|
||||
|
||||
int randomizedPartition3(std::vector<size_t>& values, int l, int r)
|
||||
{
|
||||
int n = r - l + 1;
|
||||
int pivot = rand() % n;
|
||||
std::swap(values[l + pivot], values[r]);
|
||||
|
||||
int x = values[r], i = l;
|
||||
for (int j = l; j <= r - 1; j++)
|
||||
{
|
||||
if (values[j] <= x)
|
||||
{
|
||||
std::swap(values[i], values[j]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
std::swap(values[i], values[r]);
|
||||
return i;
|
||||
}
|
||||
|
||||
int randomizedSelect(std::vector<size_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)
|
||||
*/
|
||||
|
||||
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]
|
||||
//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 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user