Skip to content

Commit 050853b

Browse files
committedMar 27, 2016
Add quick sort in es6
1 parent 6e271ad commit 050853b

File tree

2 files changed

+201
-0
lines changed

2 files changed

+201
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// sample of arrays to sort
2+
const arrayRandom = [9, 2, 5, 6, 4, 3, 7, 10, 1, 8];
3+
const arrayOrdered = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4+
const arrayReversed = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
5+
6+
let countOuter = 0;
7+
let countInner = 0;
8+
let countSwap = 0;
9+
10+
function resetCounters() {
11+
countOuter = 0;
12+
countInner = 0;
13+
countSwap = 0;
14+
}
15+
16+
// basic implementation (pivot is the first element of the array)
17+
function quicksortBasic(array) {
18+
countOuter++;
19+
if(array.length < 2) {
20+
return array;
21+
}
22+
23+
const pivot = array[0];
24+
const lesser = [];
25+
const greater = [];
26+
27+
for(let i = 1; i < array.length; i++) {
28+
countInner++;
29+
if(array[i] < pivot) {
30+
lesser.push(array[i]);
31+
} else {
32+
greater.push(array[i]);
33+
}
34+
}
35+
36+
return quicksortBasic(lesser).concat(pivot, quicksortBasic(greater));
37+
}
38+
39+
quicksortBasic(arrayRandom.slice()); // => outer: 13 inner: 25 swap: 0
40+
console.log('outer:', countOuter, 'inner:', countInner, 'swap:', countSwap);
41+
resetCounters();
42+
43+
quicksortBasic(arrayOrdered.slice()); // => outer: 19 inner: 45 swap: 0
44+
console.log('outer:', countOuter, 'inner:', countInner, 'swap:', countSwap);
45+
resetCounters();
46+
47+
quicksortBasic(arrayReversed.slice()); // => outer: 19 inner: 45 swap: 0
48+
console.log('outer:', countOuter, 'inner:', countInner, 'swap:', countSwap);
49+
resetCounters();
50+
51+
// classic implementation (with Hoare or Lomuto partition scheme, you can comment either one method or the other to see the difference)
52+
function quicksort(array, left, right) {
53+
countOuter++;
54+
left = left || 0;
55+
right = right || array.length - 1;
56+
57+
// const pivot = partitionLomuto(array, left, right); // you can play with both partition
58+
const pivot = partitionHoare(array, left, right); // you can play with both partition
59+
60+
if(left < pivot - 1) {
61+
quicksort(array, left, pivot - 1);
62+
}
63+
if(right > pivot) {
64+
quicksort(array, pivot, right);
65+
}
66+
return array;
67+
}
68+
// Lomuto partition scheme, it is less efficient than the Hoare partition scheme
69+
function partitionLomuto(array, left, right) {
70+
const pivot = right;
71+
let i = left;
72+
let last = left;
73+
74+
for(var j = left; j < right; j++) {
75+
countInner++;
76+
if(array[j] <= array[pivot]) {
77+
countSwap++;
78+
[array[i], array[j]] = [array[j], array[i]];
79+
i = i + 1;
80+
}
81+
last = j + 1;
82+
}
83+
countSwap++;
84+
[array[i], array[last]] = [array[last], array[i]];
85+
return i;
86+
}
87+
// Hoare partition scheme, it is more efficient than the Lomuto partition scheme because it does three times fewer swaps on average
88+
function partitionHoare(array, left, right) {
89+
const pivot = Math.floor((left + right) / 2 );
90+
91+
while(left <= right) {
92+
countInner++;
93+
while(array[left] < array[pivot]) {
94+
left++;
95+
}
96+
while(array[right] > array[pivot]) {
97+
right--;
98+
}
99+
if(left <= right) {
100+
countSwap++;
101+
[array[left], array[right]] = [array[right], array[left]];
102+
left++;
103+
right--;
104+
}
105+
}
106+
return left;
107+
}
108+
109+
quicksort(arrayRandom.slice());
110+
// => Hoare: outer: 9 inner: 12 swap: 12 - Lomuto: outer: 10 inner: 35 swap: 28
111+
console.log('outer:', countOuter, 'inner:', countInner, 'swap:', countSwap);
112+
resetCounters();
113+
114+
quicksort(arrayOrdered.slice());
115+
// => Hoare: outer: 9 inner: 9 swap: 9 - Lomuto: outer: 9 inner: 45 swap: 54
116+
console.log('outer:', countOuter, 'inner:', countInner, 'swap:', countSwap);
117+
resetCounters();
118+
119+
quicksort(arrayReversed.slice());
120+
// => Hoare: outer: 9 inner: 13 swap: 13 - Lomuto: outer: 10 inner: 54 swap: 39
121+
console.log('outer:', countOuter, 'inner:', countInner, 'swap:', countSwap);
122+
resetCounters();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// array to sort
2+
const array = [9, 2, 5, 6, 4, 3, 7, 10, 1, 8];
3+
4+
// basic implementation (pivot is the first element of the array)
5+
function quicksortBasic(array) {
6+
if(array.length < 2) {
7+
return array;
8+
}
9+
10+
const pivot = array[0];
11+
const lesser = [];
12+
const greater = [];
13+
14+
for(let i = 1; i < array.length; i++) {
15+
if(array[i] < pivot) {
16+
lesser.push(array[i]);
17+
} else {
18+
greater.push(array[i]);
19+
}
20+
}
21+
22+
return quicksortBasic(lesser).concat(pivot, quicksortBasic(greater));
23+
}
24+
25+
console.log(quicksortBasic(array.slice())); // => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
26+
27+
// classic implementation (with Hoare or Lomuto partition scheme, you can comment either one method or the other to see the difference)
28+
function quicksort(array, left, right) {
29+
left = left || 0;
30+
right = right || array.length - 1;
31+
32+
// const pivot = partitionLomuto(array, left, right); // you can play with both partition
33+
const pivot = partitionHoare(array, left, right); // you can play with both partition
34+
35+
if(left < pivot - 1) {
36+
quicksort(array, left, pivot - 1);
37+
}
38+
if(right > pivot) {
39+
quicksort(array, pivot, right);
40+
}
41+
return array;
42+
}
43+
// Lomuto partition scheme, it is less efficient than the Hoare partition scheme
44+
function partitionLomuto(array, left, right) {
45+
const pivot = right;
46+
let i = left;
47+
let last = left;
48+
49+
for(let j = left; j < right; j++) {
50+
if(array[j] <= array[pivot]) {
51+
[array[i], array[j]] = [array[j], array[i]];
52+
i = i + 1;
53+
}
54+
last = j + 1;
55+
}
56+
[array[i], array[last]] = [array[last], array[i]];
57+
return i;
58+
}
59+
// Hoare partition scheme, it is more efficient than the Lomuto partition scheme because it does three times fewer swaps on average
60+
function partitionHoare(array, left, right) {
61+
const pivot = Math.floor((left + right) / 2 );
62+
63+
while(left <= right) {
64+
while(array[left] < array[pivot]) {
65+
left++;
66+
}
67+
while(array[right] > array[pivot]) {
68+
right--;
69+
}
70+
if(left <= right) {
71+
[array[left], array[right]] = [array[right], array[left]];
72+
left++;
73+
right--;
74+
}
75+
}
76+
return left;
77+
}
78+
79+
console.log(quicksort(array.slice())); // => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

0 commit comments

Comments
 (0)
Please sign in to comment.