-
Notifications
You must be signed in to change notification settings - Fork 0
/
quicksorts.js
81 lines (76 loc) · 2.58 KB
/
quicksorts.js
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
function choosePivotFirst(arr, begin, end) {
return begin;
}
function choosePivotFinal(arr, begin, end) {
return end;
}
function isOdd(num) {
return num % 2;
}
function getMiddleElemIdx(arr, begin, end) {
const length = end - begin + 1;
if (isOdd(length)) {
return begin + Math.floor(length / 2);
} else {
return begin + Math.floor(length / 2) - 1;
}
}
function choosePivotMedian(arr, begin, end) {
const first = arr[begin];
const middleIdx = getMiddleElemIdx(arr, begin, end);
const middle = arr[middleIdx];
const last = arr[end];
if ((first < middle && middle < last) || (last < middle && middle < first)) {
return middleIdx;
} else if ((middle < first && first < last) || (last < first && first < middle)) {
return begin;
} else {
return end;
}
}
function swapInPlace(arr, i, j) {
var a = arr[i];
arr[i] = arr[j];
arr[j] = a;
}
function partition(arr, begin, p, end) {
if (p > begin) {
swapInPlace(arr, p, begin); // place pivot element at the beginning of subarray
}
var pivot = arr[begin]; // we've placed pivot at the beginning of subarray
var i = begin + 1; // pointer to boundary between elements that less than pivot and greater than pivot
for (var j = i; j <= end; j++) {
//scanning through remaining array
if (arr[j] < pivot) {
swapInPlace(arr, i, j);// swap is redundant when i===j, but this still will work
i++;//advance pointer to boundary
}
}
swapInPlace(arr, begin, i - 1);//place pivot element into its correct place, before boundary
return i - 1;// the boundary between two partitioned parts of subarray
}
function quicksort(arr, choosePivotFn, begin, end) {
if (end <= begin) {
return 0; //base case
} else {
const p = choosePivotFn(arr, begin, end);
var comparsions = (end - begin + 1) - 1;
var boundary = partition(arr, begin, p, end);
comparsions += quicksort(arr, choosePivotFn, begin, boundary - 1);
comparsions += quicksort(arr, choosePivotFn, boundary + 1, end);
return comparsions;
}
}
module.exports = {
first: function quicksortFirst(arr) {
return quicksort(arr, choosePivotFirst, 0, arr.length - 1)
},
final: function quicksortFinal(arr) {
return quicksort(arr, choosePivotFinal, 0, arr.length - 1)
},
median: function quicksortMedian(arr) {
return quicksort(arr, choosePivotMedian, 0, arr.length - 1)
},
getMiddleElemIdx: getMiddleElemIdx,
choosePivotMedian: choosePivotMedian
};