Skip to content

Commit ed2abde

Browse files
committed
Add merge sort.
1 parent b17ba61 commit ed2abde

File tree

5 files changed

+148
-0
lines changed

5 files changed

+148
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* [Selection Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/selection-sort)
3636
* [Insertion Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/insertion-sort)
3737
* [Heap Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/heap-sort)
38+
* [Merge Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/merge-sort)
3839

3940
## Running Tests
4041

src/algorithms/sorting/SortTester.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export class SortTester {
3232
expect(sorter.sort([''])).toEqual(['']);
3333
expect(sorter.sort(['a'])).toEqual(['a']);
3434
expect(sorter.sort(['aa', 'a'])).toEqual(['a', 'aa']);
35+
expect(sorter.sort(['aa', 'q', 'a', 'bbbb', 'ccc'])).toEqual(['q', 'a', 'aa', 'ccc', 'bbbb']);
3536
expect(sorter.sort(['aa', 'aa'])).toEqual(['aa', 'aa']);
3637
}
3738

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import Sort from '../Sort';
2+
3+
export default class MergeSort extends Sort {
4+
sort(originalArray) {
5+
// Call visiting callback.
6+
this.callbacks.visitingCallback(null);
7+
8+
// If array is empty or consists of one element then return this array since it is sorted.
9+
if (originalArray.length <= 1) {
10+
return originalArray;
11+
}
12+
13+
// Split array on two halves.
14+
const middleIndex = Math.floor(originalArray.length / 2);
15+
const leftArray = originalArray.slice(0, middleIndex);
16+
const rightArray = originalArray.slice(middleIndex, originalArray.length);
17+
18+
// Sort two halves of split array
19+
const leftSortedArray = this.sort(leftArray);
20+
const rightSortedArray = this.sort(rightArray);
21+
22+
// Merge two sorted arrays into one.
23+
return this.mergeSortedArrays(leftSortedArray, rightSortedArray);
24+
}
25+
26+
mergeSortedArrays(leftArray, rightArray) {
27+
let sortedArray = [];
28+
29+
// In case if arrays are not of size 1.
30+
while (leftArray.length && rightArray.length) {
31+
let minimumElement = null;
32+
33+
// Find minimum element of two arrays.
34+
if (this.comparator.lessThenOrEqual(leftArray[0], rightArray[0])) {
35+
minimumElement = leftArray.shift();
36+
} else {
37+
minimumElement = rightArray.shift();
38+
}
39+
40+
// Call visiting callback.
41+
this.callbacks.visitingCallback(minimumElement);
42+
43+
// Push the minimum element of two arrays to the sorted array.
44+
sortedArray.push(minimumElement);
45+
}
46+
47+
// If one of two array still have elements we need to just concatenate
48+
// this element to the sorted array since it is already sorted.
49+
if (leftArray.length) {
50+
sortedArray = sortedArray.concat(leftArray);
51+
}
52+
53+
if (rightArray.length) {
54+
sortedArray = sortedArray.concat(rightArray);
55+
}
56+
57+
return sortedArray;
58+
}
59+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Merge Sort
2+
3+
In computer science, merge sort (also commonly spelled
4+
mergesort) is an efficient, general-purpose,
5+
comparison-based sorting algorithm. Most implementations
6+
produce a stable sort, which means that the implementation
7+
preserves the input order of equal elements in the sorted
8+
output. Mergesort is a divide and conquer algorithm that
9+
was invented by John von Neumann in 1945.
10+
11+
An example of merge sort. First divide the list into
12+
the smallest unit (1 element), then compare each
13+
element with the adjacent list to sort and merge the
14+
two adjacent lists. Finally all the elements are sorted
15+
and merged.
16+
17+
![Merge Sort](https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif)
18+
19+
A recursive merge sort algorithm used to sort an array of 7
20+
integer values. These are the steps a human would take to
21+
emulate merge sort (top-down).
22+
23+
![Merge Sort](https://upload.wikimedia.org/wikipedia/commons/e/e6/Merge_sort_algorithm_diagram.svg)
24+
25+
## References
26+
27+
[Wikipedia](https://en.wikipedia.org/wiki/Merge_sort)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import BubbleSort from '../MergeSort';
2+
import {
3+
equalArr,
4+
notSortedArr,
5+
reverseArr,
6+
sortedArr,
7+
SortTester,
8+
} from '../../SortTester';
9+
10+
// Complexity constants.
11+
const SORTED_ARRAY_VISITING_COUNT = 79;
12+
const NOT_SORTED_ARRAY_VISITING_COUNT = 102;
13+
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 87;
14+
const EQUAL_ARRAY_VISITING_COUNT = 79;
15+
16+
describe('MergeSort', () => {
17+
it('should sort array', () => {
18+
SortTester.testSort(BubbleSort);
19+
});
20+
21+
it('should sort array with custom comparator', () => {
22+
SortTester.testSortWithCustomComparator(BubbleSort);
23+
});
24+
25+
// it('should do stable sorting', () => {
26+
// SortTester.testSortStability(BubbleSort);
27+
// });
28+
29+
it('should visit EQUAL array element specified number of times', () => {
30+
SortTester.testAlgorithmTimeComplexity(
31+
BubbleSort,
32+
equalArr,
33+
EQUAL_ARRAY_VISITING_COUNT,
34+
);
35+
});
36+
37+
it('should visit SORTED array element specified number of times', () => {
38+
SortTester.testAlgorithmTimeComplexity(
39+
BubbleSort,
40+
sortedArr,
41+
SORTED_ARRAY_VISITING_COUNT,
42+
);
43+
});
44+
45+
it('should visit NOT SORTED array element specified number of times', () => {
46+
SortTester.testAlgorithmTimeComplexity(
47+
BubbleSort,
48+
notSortedArr,
49+
NOT_SORTED_ARRAY_VISITING_COUNT,
50+
);
51+
});
52+
53+
it('should visit REVERSE SORTED array element specified number of times', () => {
54+
SortTester.testAlgorithmTimeComplexity(
55+
BubbleSort,
56+
reverseArr,
57+
REVERSE_SORTED_ARRAY_VISITING_COUNT,
58+
);
59+
});
60+
});

0 commit comments

Comments
 (0)