@@ -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