9.1 Minimum and maximum
1 2 3 4 5 6 7 8 9 10 11 12 | int MINIMUM(int A[], int n) { int min = A[0]; for (int i = 1; i < n; i++) { if (min > A[i]) { min = A[i]; } } return min; } |
1 2 3 4 5 6 7 8 9 10 11 12 | int MAXIMUM(int A[], int n) { int max = A[0]; for (int i = 1; i < n; i++) { if (max < A[i]) { max = A[i]; } } return max; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int second_MINIMUM(int A[], int n) { int min = A[0]; int sub_min = A[0]; for (int i = 1; i < n; i++) { if (min > A[i]) { sub_min = min; min = A[i]; } } return sub_min; } |
9.2 Selection in expected linear time
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | int PARTITION(int A[], int p, int r) { int x = A[r]; //pivot int i = p - 1; for (int j = p; j < r - 1; j++) { if (A[j] <= x) { i++; std::swap(A[i], A[j]); } } std::swap(A[i + 1], A[r]); return i + 1; } int RANDOMIZED_SELECT(int A[], int p, int r, int i) { if (p == r) return A[p]; int q = PARTITION(A, p, r); int k = q - p + 1; if (i-1 == k) return A[q]; else if (i < k) return RANDOMIZED_SELECT(A, p, q - 1, i); else return RANDOMIZED_SELECT(A, q + 1, r, i - k); } |
9.3 Selection in worst-case linear time
Median of medians https://en.wikipedia.org/wiki/Median_of_medians
-
Divide the n elements of the input array into bn=5c groups of 5 elements each and at most one group made up of the remaining n mod 5 elements.
-
Find the median of each of the dn=5e groups by first insertion-sorting the elements of each group (of which there are at most 5) and then picking the median from the sorted list of group elements.
-
Use SELECT recursively to find the median x of the dn=5e medians found in step 2. (If there are an even number of medians, then by our convention, x is the lower median.)
-
Partition the input array around the median-of-medians x using the modified version of PARTITION. Let k be one more than the number of elements on the low side of the partition, so that x is the kth smallest element and there are nk elements on the high side of the partition.
-
If i D k, then return x. Otherwise, use SELECT recursively to find the i th smallest element on the low side if i < k, or the .i k/th smallest element on the high side if i > k.
https://www.geeksforgeeks.org/kth-smallestlargest-element-unsorted-array-set-3-worst-case-linear-time/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | // C++ implementation of worst case linear time algorithm // to find k'th smallest element #include<iostream> #include<algorithm> #include<climits> using namespace std; int partition(int arr[], int l, int r, int k); // A simple function to find median of arr[]. This is called // only for an array of size 5 in this program. int findMedian(int arr[], int n) { sort(arr, arr + n); // Sort the array return arr[n / 2]; // Return middle element } // Returns k'th smallest element in arr[l..r] in worst case // linear time. ASSUMPTION: ALL ELEMENTS IN ARR[] ARE DISTINCT int kthSmallest(int 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. int i; int *median = new int[(n + 4) / 5]; // There will be floor((n+4)/5) groups; 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] : kthSmallest(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); delete[]median; // 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 kthSmallest(arr, l, pos - 1, k); // Else recur for right subarray return kthSmallest(arr, pos + 1, r, k - pos + l - 1); } // If k is more than number of elements in array return INT_MAX; } void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // It searches for x in arr[l..r], and partitions the array // around x. int partition(int arr[], int l, int r, int x) { // Search for x in arr[l..r] and move it to end int i; for (i = l; i < r; i++) if (arr[i] == x) break; swap(&arr[i], &arr[r]); // Standard partition algorithm i = l; for (int j = l; j <= r - 1; j++) { if (arr[j] <= x) { swap(&arr[i], &arr[j]); i++; } } swap(&arr[i], &arr[r]); return i; } // Driver program to test above methods int main() { int arr[] = { 12, 3, 5, 7, 4, 19, 26 }; int n = sizeof(arr) / sizeof(arr[0]), k = 5; cout << "K'th smallest element is " << kthSmallest(arr, 0, n - 1, k); return 0; } |