From c8db9109c69291b00c4130b9841d69194a1c7707 Mon Sep 17 00:00:00 2001 From: incredibleLeitman Date: Sat, 17 Oct 2020 00:30:07 +0200 Subject: [PATCH] using uint32 instead of size_t --- MedianOfMedians.h | 96 ++++++++++++++++++++--------------------------- MedianQuicksort.h | 14 +++---- 2 files changed, 47 insertions(+), 63 deletions(-) diff --git a/MedianOfMedians.h b/MedianOfMedians.h index 7f8da59..c05d9b6 100644 --- a/MedianOfMedians.h +++ b/MedianOfMedians.h @@ -4,32 +4,29 @@ // 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 values) +uint32_t findMedian(std::vector values) { - size_t median; - size_t size = values.size(); - median = values[(size / 2)]; - return median; + return values[(values.size() / 2)]; } -int findMedianOfMedians(std::vector > values) +uint32_t findMedianOfMedians(std::vector > values) { - std::vector medians; + std::vector medians; for (size_t i = 0; i < values.size(); i++) { - size_t m = findMedian(values[i]); + uint32_t m = findMedian(values[i]); medians.push_back(m); } return findMedian(medians); } -size_t getMedianOfMedians(const std::vector values, size_t k) +uint32_t getMedianOfMedians(const std::vector values, uint32_t k) { // Divide the list into n/5 lists of 5 elements each - std::vector > vec2D; + std::vector > vec2D; size_t count = 0; while (count != values.size()) { size_t countRow = 0; - std::vector row; + std::vector row; while ((countRow < 5) && (count < values.size())) { row.push_back(values[count]); @@ -40,10 +37,10 @@ size_t getMedianOfMedians(const std::vector values, size_t k) } // Calculating a new pivot for making splits - size_t m = findMedianOfMedians(vec2D); + uint32_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 L1, L2; + std::vector L1, L2; for (size_t i = 0; i < vec2D.size(); i++) { @@ -73,19 +70,19 @@ size_t getMedianOfMedians(const std::vector values, size_t k) // 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) +uint32_t findMedian(uint32_t arr[], int n) { std::sort(arr, arr + n); // Sort the array return arr[n / 2]; // Return middle element } // searches for x in arr[l..r], and partitions the array around x -int partition(size_t arr[], int l, int r, int x) +int partition(uint32_t arr[], int l, int r, uint32_t pivotValue) { // Search for x in arr[l..r] and move it to end int i; for (i = l; i < r; i++) - if (arr[i] == x) + if (arr[i] == pivotValue) break; swap(&arr[i], &arr[r]); @@ -93,7 +90,7 @@ int partition(size_t arr[], int l, int r, int x) i = l; for (int j = l; j < r; j++) { - if (arr[j] <= x) + if (arr[j] <= pivotValue) { i++; swap(&arr[i], &arr[j]); @@ -106,47 +103,34 @@ int partition(size_t arr[], int l, int r, int x) // Returns k'th smallest element in arr[l..r] in worst case // linear time. ASSUMPTION: ALL ELEMENTS IN ARR[] ARE DISTINCT //int getMedianOfMedians(int arr[], int l, int r, int k) -size_t getMedianOfMedians(size_t* arr, int l, int r, int k) +uint32_t getMedianOfMedians(uint32_t* arr, int l, int r, int k) { - // If k is smaller than number of elements in array - if (k > 0 && k <= r - l + 1) + int n = r - l + 1; // Number of elements in arr[l..r] + + // Divide arr[] in groups of size 5, calculate median + // of every group and store it in median[] array. + // There will be floor((n + 4) / 5) groups; + //int median[(n + 4) / 5]; // non VS compliant! + uint32_t* median = new uint32_t[(n + 4) / 5]; + int i = 0; + for (i = 0; i < n / 5; i++) + median[i] = findMedian(arr + l + i * 5, 5); + if (i * 5 < n) //For last group with less than 5 elements { - int n = r - l + 1; // Number of elements in arr[l..r] - - // Divide arr[] in groups of size 5, calculate median - // of every group and store it in median[] array. - // There will be floor((n + 4) / 5) groups; - //int median[(n + 4) / 5]; // non VS compliant! - size_t* median = new size_t[(n + 4) / 5]; - int i = 0; - for (i = 0; i < n / 5; i++) - median[i] = findMedian(arr + l + i * 5, 5); - if (i * 5 < n) //For last group with less than 5 elements - { - median[i] = findMedian(arr + l + i * 5, n % 5); - i++; - } - - // Find median of all medians using recursive call. - // If median[] has only one element, then no need - // of recursive call - int medOfMed = (i == 1) ? median[i - 1] : - getMedianOfMedians(median, 0, i - 1, i / 2); - - // Partition the array around a random element and - // get position of pivot element in sorted array - int pos = partition(arr, l, r, medOfMed); - - // If position is same as k - if (pos - l == k - 1) - return arr[pos]; - if (pos - l > k - 1) // If position is more, recur for left - return getMedianOfMedians(arr, l, pos - 1, k); - - // Else recur for right subarray - return getMedianOfMedians(arr, pos + 1, r, k - pos + l - 1); + median[i] = findMedian(arr + l + i * 5, n % 5); + i++; } - // If k is more than number of elements in array - return SIZE_MAX; + // Find median of all medians using recursive call. + // If median[] has only one element, then no need for recursive call + uint32_t medOfMed = (i == 1) ? median[0] : getMedianOfMedians(median, 0, i - 1, i / 2); + + // Partition the array around a random element and + // get position of pivot element in sorted array + int pos = partition(arr, l, r, medOfMed); + + if (pos - l == k - 1) return arr[pos]; + else if (pos - l > k - 1) + return getMedianOfMedians(arr, l, pos - 1, k); + else return getMedianOfMedians(arr, pos + 1, r, k - pos + l - 1); } diff --git a/MedianQuicksort.h b/MedianQuicksort.h index 93dc8d3..d918e7f 100644 --- a/MedianQuicksort.h +++ b/MedianQuicksort.h @@ -1,8 +1,8 @@ #pragma once -size_t pivotPartition(std::vector& values, size_t left, size_t right) { - size_t pivotIndex = left + (right - left) / 2; - size_t pivotValue = values[pivotIndex]; +uint32_t pivotPartition(std::vector& 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) { @@ -15,7 +15,7 @@ size_t pivotPartition(std::vector& values, size_t left, size_t right) { j--; } if (i <= j) { - std::swap(values[i], values[j]); + swap(&values[i], &values[j]); i++; j--; } @@ -23,16 +23,16 @@ size_t pivotPartition(std::vector& values, size_t left, size_t right) { return i; } -void quicksort(std::vector& values, size_t left, size_t right) +void quicksort(std::vector& values, uint32_t left, uint32_t right) { if (left < right) { - size_t pivotIndex = pivotPartition(values, left, right); + uint32_t pivotIndex = pivotPartition(values, left, right); quicksort(values, left, pivotIndex - 1); quicksort(values, pivotIndex, right); } } -size_t getQuicksortMedian(std::vector values, size_t i) +uint32_t getQuicksortMedian(std::vector values, uint32_t i) { //std::qsort(numbers); // only takes array param -> custom implementation with vector quicksort(values, 0, values.size() - 1);