Skip to content

Commit cbd6545

Browse files
committed
added bubbleSort+shellSort and made tests run for all functions
1 parent 759ba8e commit cbd6545

File tree

1 file changed

+141
-95
lines changed

1 file changed

+141
-95
lines changed

sorting-algorithms.js

Lines changed: 141 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ function swap(arr, i, j) {
44
arr[j] = tmp;
55
}
66

7-
function selectionSort(arr, onUpdate=console.log) {
8-
onUpdate(arr);
7+
function selectionSort(arr) {
98
for (let i = 0; i < arr.length - 1; i++) {
109
let minIdx = i;
1110
for (let j = i + 1; j < arr.length; j++) {
@@ -14,25 +13,22 @@ function selectionSort(arr, onUpdate=console.log) {
1413
}
1514
}
1615
swap(arr, i, minIdx);
17-
onUpdate(arr);
1816
}
1917

2018
return arr;
2119
}
2220

23-
function insertionSort(arr, onUpdate=console.log) {
24-
onUpdate(arr);
21+
function insertionSort(arr) {
2522
for (let i = 1; i < arr.length; i++) {
2623
for (let j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
2724
swap(arr, j, j - 1);
2825
}
29-
onUpdate(arr);
3026
}
3127

3228
return arr;
3329
}
3430

35-
function mergeSort(arr, onUpdate=console.log) {
31+
function mergeSort(arr) {
3632

3733
function merge(arr, workArr, leftIdx, middleIdx, rightIdx) {
3834
let i = leftIdx;
@@ -65,7 +61,7 @@ function mergeSort(arr, onUpdate=console.log) {
6561
return arr;
6662
}
6763

68-
function heapSort(arr, onUpdate=console.log) {
64+
function heapSort(arr) {
6965

7066
function maxHeapify(arr, i, end) {
7167
let left = 2 * i + 1;
@@ -131,98 +127,148 @@ function quickSort(arr, lo=null, hi=null) {
131127
return arr;
132128
}
133129

134-
// TEST CASES
130+
function bubbleSort(arr) {
131+
while (true) {
132+
didSwap = false
133+
for (let i = 1; i < arr.length; i++) {
134+
if (arr[i] < arr[i - 1]) {
135+
swap(arr, i, i - 1);
136+
didSwap = true
137+
}
138+
}
139+
if (!didSwap) {
140+
break
141+
}
142+
}
135143

136-
function compareNumbers(a, b) {
137-
return a - b;
144+
return arr
138145
}
139146

140-
let arr10Items = randArr(10);
141-
let arr10ItemsSorted = [...arr10Items].sort(compareNumbers);
142-
let arr100Items = randArr(100);
143-
let arr100ItemsSorted = [...arr100Items].sort(compareNumbers);
144-
let arr1000Items = randArr(1000);
145-
let arr1000ItemsSorted = [...arr1000Items].sort(compareNumbers);
146-
let arr10000Items = randArr(10000);
147-
let arr10000ItemsSorted = [...arr10000Items].sort(compareNumbers);
148-
149-
let cases = [
150-
{
151-
name: 'three elements',
152-
arr: [3, 1, 2],
153-
expected: [1, 2, 3],
154-
},
155-
{
156-
name: 'two elements',
157-
arr: [2, 1],
158-
expected: [1, 2],
159-
},
160-
{
161-
name: 'empty array',
162-
arr: [],
163-
expected: [],
164-
},
165-
{
166-
name: 'one element',
167-
arr: [1],
168-
expected: [1],
169-
},
170-
{
171-
name: 'already sorted',
172-
arr: [1, 2, 3],
173-
expected: [1, 2, 3],
174-
},
175-
{
176-
name: 'four elements',
177-
arr: [5, 1, 3, 2],
178-
expected: [1, 2, 3, 5],
179-
},
180-
181-
{
182-
name: 'all sequential',
183-
arr: [5, 4, 1, 3, 2],
184-
expected: [1, 2, 3, 4, 5],
185-
},
186-
{
187-
name: 'with duplicate values',
188-
arr: [6, 6, 3, 3, 3, 1, 3, 2],
189-
expected: [1, 2, 3, 3, 3, 3, 6, 6],
190-
},
191-
{
192-
name: 'random array of 10 items',
193-
arr: arr10Items,
194-
expected: arr10ItemsSorted,
195-
},
196-
{
197-
name: 'random array of 100 items',
198-
arr: arr100Items,
199-
expected: arr100ItemsSorted,
200-
},
201-
{
202-
name: 'random array of 1000 items',
203-
arr: arr1000Items,
204-
expected: arr1000ItemsSorted,
205-
},
206-
{
207-
name: 'random array of 10000 items',
208-
arr: arr10000Items,
209-
expected: arr10000ItemsSorted,
210-
},
211-
]
212-
213-
function randArr(len) {
214-
let arr = [];
215-
for (let i = 0; i < len; i++) {
216-
let randVal = Math.floor(Math.random() * 1000);
217-
arr.push(randVal);
147+
function shellSort(arr) {
148+
gaps = [701, 301, 132, 57, 23, 10, 4, 1] // Ciura gap sequence
149+
for (let i = 0; i < gaps.length; i++) {
150+
let gap = gaps[i];
151+
for (let j = gap; j < arr.length; j++) {
152+
let tmp = arr[j];
153+
let k;
154+
for (k = j; k >= gap && arr[k - gap] > tmp; k -= gap) {
155+
arr[k] = arr[k - gap];
156+
}
157+
arr[k] = tmp;
158+
}
218159
}
219160
return arr;
220161
}
221162

222-
cases.forEach(function(c) {
223-
console.log(`Running test "${c.name}"...`);
224-
let result = quickSort(c.arr);
225-
if (c.expected.length != result.length || !c.expected.every(function(value, index) { return value === result[index]})) {
226-
console.error(`Got ${JSON.stringify(result)}, want ${JSON.stringify(c.expected)}`);
163+
// TEST CASES
164+
165+
166+
function runTests() {
167+
168+
function compareNumbers(a, b) {
169+
return a - b;
227170
}
228-
});
171+
172+
function randArr(len) {
173+
let arr = [];
174+
for (let i = 0; i < len; i++) {
175+
let randVal = Math.floor(Math.random() * 1000);
176+
arr.push(randVal);
177+
}
178+
return arr;
179+
}
180+
const sortFunctions = [
181+
insertionSort,
182+
selectionSort,
183+
mergeSort,
184+
heapSort,
185+
quickSort,
186+
bubbleSort,
187+
shellSort,
188+
];
189+
190+
sortFunctions.forEach(function(sort) {
191+
let arr10Items = randArr(10);
192+
let arr10ItemsSorted = [...arr10Items].sort(compareNumbers);
193+
let arr100Items = randArr(100);
194+
let arr100ItemsSorted = [...arr100Items].sort(compareNumbers);
195+
let arr1000Items = randArr(1000);
196+
let arr1000ItemsSorted = [...arr1000Items].sort(compareNumbers);
197+
let arr10000Items = randArr(10000);
198+
let arr10000ItemsSorted = [...arr10000Items].sort(compareNumbers);
199+
200+
let cases = [
201+
{
202+
name: 'three elements',
203+
arr: [3, 1, 2],
204+
expected: [1, 2, 3],
205+
},
206+
{
207+
name: 'two elements',
208+
arr: [2, 1],
209+
expected: [1, 2],
210+
},
211+
{
212+
name: 'empty array',
213+
arr: [],
214+
expected: [],
215+
},
216+
{
217+
name: 'one element',
218+
arr: [1],
219+
expected: [1],
220+
},
221+
{
222+
name: 'already sorted',
223+
arr: [1, 2, 3],
224+
expected: [1, 2, 3],
225+
},
226+
{
227+
name: 'four elements',
228+
arr: [5, 1, 3, 2],
229+
expected: [1, 2, 3, 5],
230+
},
231+
232+
{
233+
name: 'all sequential',
234+
arr: [5, 4, 1, 3, 2],
235+
expected: [1, 2, 3, 4, 5],
236+
},
237+
{
238+
name: 'with duplicate values',
239+
arr: [6, 6, 3, 3, 3, 1, 3, 2],
240+
expected: [1, 2, 3, 3, 3, 3, 6, 6],
241+
},
242+
{
243+
name: 'random array of 10 items',
244+
arr: arr10Items,
245+
expected: arr10ItemsSorted,
246+
},
247+
{
248+
name: 'random array of 100 items',
249+
arr: arr100Items,
250+
expected: arr100ItemsSorted,
251+
},
252+
{
253+
name: 'random array of 1000 items',
254+
arr: arr1000Items,
255+
expected: arr1000ItemsSorted,
256+
},
257+
{
258+
name: 'random array of 10000 items',
259+
arr: arr10000Items,
260+
expected: arr10000ItemsSorted,
261+
},
262+
]
263+
264+
cases.forEach(function(c) {
265+
console.log(`[${sort.name}] Running test "${c.name}"...`);
266+
let result = sort(c.arr);
267+
if (c.expected.length != result.length || !c.expected.every(function(value, index) { return value === result[index]})) {
268+
console.error(`Got ${JSON.stringify(result)}, want ${JSON.stringify(c.expected)}`);
269+
}
270+
});
271+
});
272+
}
273+
274+
runTests();

0 commit comments

Comments
 (0)