@@ -14,9 +14,10 @@ function checkArray(arr) {
14
14
}
15
15
16
16
/**
17
- * Bubble sort, sorted by swapping item pairs(if needed) from the start postion to the end of the array.
17
+ * Bubble sort, sorted by swapping item pairs(if needed) from the start postion to the end of the
18
+ * array.
18
19
* First round will have a largest item swapped to the array end, and second round will have the
19
- * second largest item swapped to array end minus one position, and so on until all items are sorted.
20
+ * second largest item swapped to array end - 1 position, and so on until all items are sorted.
20
21
*
21
22
* Time complexity: O(N, N^2)
22
23
* Space complexity: O(1)
@@ -28,18 +29,24 @@ function checkArray(arr) {
28
29
export function bubbleSort ( array ) {
29
30
const arr = array . slice ( ) ;
30
31
checkArray ( arr ) ;
32
+ let hasSwap = false ;
31
33
for ( let i = arr . length - 1 ; i > 0 ; i -- ) {
32
34
for ( let j = 0 ; j < i ; j ++ ) {
33
35
if ( arr [ j ] > arr [ j + 1 ] ) {
34
36
swap ( arr , j , j + 1 ) ;
37
+ hasSwap = true ;
35
38
}
36
39
}
40
+ if ( ! hasSwap ) {
41
+ return arr ;
42
+ }
37
43
}
38
44
return arr ;
39
45
}
40
46
41
47
/**
42
- * Selection sort, sorted by selecting min to max items for the start to the end position of the array.
48
+ * Selection sort, sorted by selecting min to max items for the start to the end position of the
49
+ * array.
43
50
*
44
51
* Time complexity: O(N^2)
45
52
* Space complexity: O(1)
@@ -129,12 +136,12 @@ export function shellSort(array, base = 3) {
129
136
}
130
137
131
138
/**
132
- * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is done
133
- * for the left/right partitioned parts, and so on.
139
+ * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is
140
+ * done for the left/right partitioned parts, and so on.
134
141
* The partition process will swap pairs of items until the left part are all smaller than pivot,
135
142
* and right part are all larger.
136
143
* This function implemented it by creating extra partitioned array upon each partition process.
137
- * It's concise and easy to read, but has extra space complexity than quickSort implementation below .
144
+ * It's concise and easy to read, but has extra space complexity.
138
145
*
139
146
* Time complexity: O(NlogN, N^2)
140
147
* Space complexity: O(N)
@@ -157,8 +164,8 @@ export function quickSortWithArray(array) {
157
164
}
158
165
159
166
/**
160
- * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is done
161
- * for the left/right partitioned parts, and so on.
167
+ * Quick sort, sorted by performing a partition process for a chosen pivot item, and the same is
168
+ * done for the left/right partitioned parts, and so on.
162
169
* The partition process will swap pairs of items until the left part are all smaller than pivot,
163
170
* and right part are all larger.
164
171
*
@@ -169,34 +176,37 @@ export function quickSortWithArray(array) {
169
176
* @return {Array }
170
177
*
171
178
*/
172
- export function quickSort ( arr , lo , hi ) {
173
- checkArray ( arr ) ;
179
+ export function quickSort ( array , lo , hi ) {
180
+ checkArray ( array ) ;
174
181
lo = typeof lo === "number" ? lo : 0 ;
175
- hi = typeof hi === "number" ? hi : arr . length ;
176
-
177
- if ( hi <= lo ) return arr ;
182
+ hi = typeof hi === "number" ? hi : array . length ;
183
+ if ( hi <= lo ) return array ;
178
184
179
- let start = lo ;
180
- let end = hi ;
181
- const pivot = arr [ lo ] ;
185
+ const partition = ( arr , left , right ) => {
186
+ let start = left ;
187
+ let end = right ;
188
+ const pivot = arr [ left ] ;
182
189
183
- while ( start < end ) {
184
- while ( arr [ ++ start ] <= pivot ) if ( start === hi ) break ;
185
- while ( arr [ -- end ] >= pivot ) if ( end === lo ) break ;
186
- if ( start >= end ) break ;
187
- swap ( arr , start , end ) ;
188
- }
189
- swap ( arr , lo , end ) ;
190
-
191
- quickSort ( arr , lo , end ) ;
192
- quickSort ( arr , end + 1 , hi ) ;
190
+ while ( start < end ) {
191
+ while ( arr [ ++ start ] <= pivot ) if ( start === right ) break ; // eslint-disable-line no-plusplus
192
+ while ( arr [ -- end ] >= pivot ) if ( end === left ) break ; // eslint-disable-line no-plusplus
193
+ if ( start >= end ) break ;
194
+ swap ( arr , start , end ) ;
195
+ }
196
+ swap ( arr , left , end ) ;
197
+ return end ;
198
+ } ;
199
+ const pivot = partition ( array , lo , hi ) ;
200
+ quickSort ( array , lo , pivot ) ;
201
+ quickSort ( array , pivot + 1 , hi ) ;
193
202
194
- return arr ;
203
+ return array ;
195
204
}
196
205
197
206
/**
198
- * Merge sort, sorted by recursively dividing the array into two sub-arrays and merging corresponding
199
- * sub-arrays back into a sorted array. The merge process ensures that the merged array is sorted.
207
+ * Merge sort, sorted by recursively dividing the array into two sub-arrays and merging
208
+ * corresponding sub-arrays back into a sorted array. The merge process ensures that the merged
209
+ * array is sorted.
200
210
*
201
211
* Time complexity: O(NlogN)
202
212
* Space complexity: O(N)
@@ -211,41 +221,36 @@ export function mergeSort(array) {
211
221
if ( arr . length < 2 ) {
212
222
return arr ;
213
223
}
214
- const merge = ( arr1 , arr2 ) => {
224
+ const merge = ( a , b ) => {
215
225
const result = [ ] ;
216
- const arrLen1 = arr1 . length ;
217
- const arrLen2 = arr2 . length ;
218
- let pt1 = 0 ;
219
- let pt2 = 0 ;
220
-
221
- while ( pt1 < arrLen1 && pt2 < arrLen2 ) {
222
- if ( arr1 [ pt1 ] === arr2 [ pt2 ] ) {
223
- result . push ( arr1 [ pt1 ] , arr2 [ pt2 ] ) ;
224
- pt1 += 1 ;
225
- pt2 += 1 ;
226
- } else if ( arr1 [ pt1 ] > arr2 [ pt2 ] ) {
227
- result . push ( arr2 [ pt2 ] ) ;
228
- pt2 += 1 ;
226
+ const lenA = a . length ;
227
+ const lenB = b . length ;
228
+ let i = 0 ;
229
+ let j = 0 ;
230
+ while ( i < lenA && j < lenB ) {
231
+ if ( a [ i ] === b [ j ] ) {
232
+ result . push ( a [ i ] , b [ j ] ) ;
233
+ i += 1 ;
234
+ j += 1 ;
235
+ } else if ( a [ i ] > b [ j ] ) {
236
+ result . push ( b [ j ] ) ;
237
+ j += 1 ;
229
238
} else {
230
- result . push ( arr1 [ pt1 ] ) ;
231
- pt1 += 1 ;
239
+ result . push ( a [ i ] ) ;
240
+ i += 1 ;
232
241
}
233
242
}
234
-
235
- return result . concat ( arr1 . slice ( pt1 ) ) . concat ( arr2 . slice ( pt2 ) ) ;
243
+ return result . concat ( a . slice ( i ) ) . concat ( b . slice ( j ) ) ;
236
244
} ;
237
- const mid = Math . floor ( arr . length - 1 / 2 ) ;
238
- const leftArr = arr . slice ( 0 , mid ) ;
239
- const rightArr = arr . slice ( mid ) ;
240
-
241
- return merge ( mergeSort ( leftArr ) , mergeSort ( rightArr ) ) ;
245
+ const mid = Math . floor ( arr . length / 2 ) ;
246
+ return merge ( mergeSort ( arr . slice ( 0 , mid ) ) , mergeSort ( arr . slice ( mid ) ) ) ;
242
247
}
243
248
244
249
/**
245
250
* Heap sort, sorted by using the heapify process of the Heap data structure.
246
251
* The Heap data structure looks like a binary tree, but there cannot be `null` gap within it.
247
- * A proper Heap should have the property that all parent nodes are larger than or equal to its child
248
- * nodes.
252
+ * A proper Heap should have the property that all parent nodes are larger than or equal to its
253
+ * child nodes.
249
254
* The heapify process can find the largest item of the array at a time, and then swap the largest
250
255
* item to the end of the array. This process is repeated until all the array become sorted.
251
256
*
0 commit comments