-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmergesort.js
68 lines (55 loc) · 1.36 KB
/
mergesort.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
const DEFAULT_OPTIONS = {
invert: false, /* invert order */
compare: DEFAULT_COMPARE
};
export default function MergeSort(data, opts) {
if ( ! opts ) {
opts = DEFAULT_OPTIONS;
}
opts = Object.assign({}, DEFAULT_OPTIONS, opts);
return recursiveMergeSort(data, opts);
}
export const sort = MergeSort;
function recursiveMergeSort(list, opts) {
if ( list.length <= 1 ) {
return list;
} else {
const half = list.length>>1;
const sortedLeft = recursiveMergeSort(list.slice(0,half), opts);
const sortedRight = recursiveMergeSort(list.slice(half), opts);
return merge(sortedLeft, sortedRight, opts);
}
}
function merge(a, b, opts) {
const sorted = [];
let ai = 0;
let bi = 0;
while(ai < a.length && bi < b.length) {
const comparison = signedCompare(a[ai], b[bi], opts);
const head = comparison >= 0 ? a[ai++] : b[bi++];
sorted.push(head);
}
while(ai < a.length) {
sorted.push(a[ai++]);
}
while(bi < b.length) {
sorted.push(b[bi++]);
}
return sorted;
}
export function signedCompare(a, b, {compare: compare = DEFAULT_COMPARE, invert: invert = false} = {}) {
const comparison = compare(a, b);
if ( invert ) {
return -comparison;
}
return comparison;
}
function DEFAULT_COMPARE(a, b) {
if ( a > b ) {
return -1;
} else if ( a < b ) {
return 1;
} else {
return 0;
}
}