item selection(set A, index i)
function minimum(A, n) {
let min = A[0];
for(let i = 1; i < n; ++i) {
if(min > A[i]) min = A[i];
}
return min;
}
// To find maximum: change > to <
function maxAndMin(A, n) {
let max, min;
if(n % 2 == 0) {
max = A[0] > A[1] ? A[0] : A[1];
min = A[0] === max ? A[1] : A[0];
for(let i = 2; i < n; i += 2) {
let bigger = A[i] > A[i + 1] ? A[i] : A[i + 1];
let smaller = A[i] === bigger ? A[i + 1] : A[i];
max = bigger > max ? bigger : max;
min = smaller < min ? smaller : min;
}
}
else {
max = A[0];
min = A[0];
for(let i = 1; i < n; i += 2) {
let bigger = A[i] > A[i + 1] ? A[i] : A[i + 1];
let smaller = A[i] === bigger ? A[i + 1] : A[i];
max = bigger > max ? bigger : max;
min = smaller < min ? smaller : min;
}
}
return {max, min};
}
RANDOMIZED-PARTITION
函數取得隨機的 pivot 值,並且把 input 的陣列分成比 pivot 大和比 pivot 小的兩邊
// p = first index in subarray, r = last index in subarray
function randomized_select(A, p, r, i) {
if(p === r) {
return A[p];
}
let q = randomized_partition(A, p, r); // pivot index in array A
let k = q - p + 1; // pivot index in this subarray
if(i === 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);
}
}
function partition(A, p, r) {
let random = Math.floor(Math.random() * r + 1);
swap(A, random, r);
let pivot = A[r];
let q = p;
for (let i = p; i < r; ++i) {
if (A[i] <= pivot) {
swap(A, q, i);
q++;
}
}
swap(A, r, q);
return q;
}
PARTITION
函數,並且以這個中位數們的中位數為 pivot, 將 input 陣列分成兩邊
function medianOfMedians(A, left, right, i) {
while(true) {
if(left === right) {
return A[left];
}
let pivotIndex = pivot(A, left, right);
pivotIndex = partition(A, left, right, pivotIndex);
if(i === pivotIndex) {
return A[pivotIndex];
}
else if(i < pivotIndex) {
right = pivotIndex - 1;
}
else {
left = pivotIndex + 1;
}
}
}
function pivot(A, left, right) {
if(right - left < 5) {
return insertion_sort(A, left, right);
}
for(let i = left; i <= right; i += 5) {
let subRight = i + 4;
if(subRight > right) {
subRight = right;
}
let median5 = insertion_sort(A, i, subRight);
swap(A[median5], A[left + Math.floor((i - left) / 5)]);
}
return medianOfMedians(A,
left,
left + Math.floor((right - left) / 5),
left + Math.floor((right - left) / 10));
}
function partition(A, left, right, pivotIndex) {
let pivotValue = A[pivotIndex];
swap(A[pivotIndex], A[right]);
let storeIndex = left;
for(let i = left; i < right; ++i) {
if(A[i] < pivotValue) {
swap(A[storeIndex], A[i]);
storeIndex++;
}
}
swap(A[storeIndex], A[right]);
return storeIndex;
}
function insertion_sort(A, left, right) {
let i, j, tmp;
for(i = left + 1; i <= right; ++i){
let tmp = A[i];
for(j = i; j > left && A[j - 1] > tmp; j--) {
A[j] = A[j - 1];
}
A[j] = tmp;
}
return left + Math.floor((right - left) / 2);
}
PARTITION
函數將 input 陣列分成兩邊: medianOfMedians
的時候,頂多只會處理