Skip to content

Commit 36bbfed

Browse files
committedApr 14, 2018
Add heap sort.
1 parent 053b365 commit 36bbfed

File tree

9 files changed

+143
-38
lines changed

9 files changed

+143
-38
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* [Bubble Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/bubble-sort)
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)
37+
* [Heap Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/heap-sort)
3738

3839
## Running Tests
3940

‎src/algorithms/sorting/bubble-sort/__test__/BubbleSort.test.js

+10-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import {
77
SortTester,
88
} from '../../SortTester';
99

10+
// Complexity constants.
11+
const SORTED_ARRAY_VISITING_COUNT = 20;
12+
const NOT_SORTED_ARRAY_VISITING_COUNT = 280;
13+
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 400;
14+
const EQUAL_ARRAY_VISITING_COUNT = 20;
15+
1016
describe('BubbleSort', () => {
1117
it('should sort array', () => {
1218
SortTester.testSort(BubbleSort);
@@ -21,42 +27,34 @@ describe('BubbleSort', () => {
2127
});
2228

2329
it('should visit EQUAL array element specified number of times', () => {
24-
const expectedNumberOfVisits = 20;
25-
2630
SortTester.testAlgorithmTimeComplexity(
2731
BubbleSort,
2832
equalArr,
29-
expectedNumberOfVisits,
33+
EQUAL_ARRAY_VISITING_COUNT,
3034
);
3135
});
3236

3337
it('should visit SORTED array element specified number of times', () => {
34-
const expectedNumberOfVisits = 20;
35-
3638
SortTester.testAlgorithmTimeComplexity(
3739
BubbleSort,
3840
sortedArr,
39-
expectedNumberOfVisits,
41+
SORTED_ARRAY_VISITING_COUNT,
4042
);
4143
});
4244

4345
it('should visit NOT SORTED array element specified number of times', () => {
44-
const expectedNumberOfVisits = 280;
45-
4646
SortTester.testAlgorithmTimeComplexity(
4747
BubbleSort,
4848
notSortedArr,
49-
expectedNumberOfVisits,
49+
NOT_SORTED_ARRAY_VISITING_COUNT,
5050
);
5151
});
5252

5353
it('should visit REVERSE SORTED array element specified number of times', () => {
54-
const expectedNumberOfVisits = 400;
55-
5654
SortTester.testAlgorithmTimeComplexity(
5755
BubbleSort,
5856
reverseArr,
59-
expectedNumberOfVisits,
57+
REVERSE_SORTED_ARRAY_VISITING_COUNT,
6058
);
6159
});
6260
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Sort from '../Sort';
2+
import MinHeap from '../../../data-structures/heap/MinHeap';
3+
4+
export default class HeapSort extends Sort {
5+
sort(originalArray) {
6+
const sortedArray = [];
7+
const minHeap = new MinHeap(this.callbacks.compareCallback);
8+
9+
// Insert all array elements to the heap.
10+
originalArray.forEach((element) => {
11+
// Call visiting callback.
12+
this.callbacks.visitingCallback(element);
13+
14+
minHeap.add(element);
15+
});
16+
17+
// Now we have min heap with minimal element always on top.
18+
// Let's poll that minimal element one by one and thus form the sorted array.
19+
while (!minHeap.isEmpty()) {
20+
const nextMinElement = minHeap.poll();
21+
22+
// Call visiting callback.
23+
this.callbacks.visitingCallback(nextMinElement);
24+
25+
sortedArray.push(nextMinElement);
26+
}
27+
28+
return sortedArray;
29+
}
30+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Heap Sort
2+
3+
Heapsort is a comparison-based sorting algorithm.
4+
Heapsort can be thought of as an improved selection
5+
sort: like that algorithm, it divides its input into
6+
a sorted and an unsorted region, and it iteratively
7+
shrinks the unsorted region by extracting the largest
8+
element and moving that to the sorted region. The
9+
improvement consists of the use of a heap data structure
10+
rather than a linear-time search to find the maximum.
11+
12+
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/1/1b/Sorting_heapsort_anim.gif)
13+
14+
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/4/4d/Heapsort-example.gif)
15+
16+
## References
17+
18+
[Wikipedia](https://en.wikipedia.org/wiki/Heapsort)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import HeapSort from '../HeapSort';
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 = 40;
12+
const NOT_SORTED_ARRAY_VISITING_COUNT = 40;
13+
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 40;
14+
const EQUAL_ARRAY_VISITING_COUNT = 40;
15+
16+
describe('HeapSort', () => {
17+
it('should sort array', () => {
18+
SortTester.testSort(HeapSort);
19+
});
20+
21+
it('should sort array with custom comparator', () => {
22+
SortTester.testSortWithCustomComparator(HeapSort);
23+
});
24+
25+
it('should visit EQUAL array element specified number of times', () => {
26+
SortTester.testAlgorithmTimeComplexity(
27+
HeapSort,
28+
equalArr,
29+
EQUAL_ARRAY_VISITING_COUNT,
30+
);
31+
});
32+
33+
it('should visit SORTED array element specified number of times', () => {
34+
SortTester.testAlgorithmTimeComplexity(
35+
HeapSort,
36+
sortedArr,
37+
SORTED_ARRAY_VISITING_COUNT,
38+
);
39+
});
40+
41+
it('should visit NOT SORTED array element specified number of times', () => {
42+
SortTester.testAlgorithmTimeComplexity(
43+
HeapSort,
44+
notSortedArr,
45+
NOT_SORTED_ARRAY_VISITING_COUNT,
46+
);
47+
});
48+
49+
it('should visit REVERSE SORTED array element specified number of times', () => {
50+
SortTester.testAlgorithmTimeComplexity(
51+
HeapSort,
52+
reverseArr,
53+
REVERSE_SORTED_ARRAY_VISITING_COUNT,
54+
);
55+
});
56+
});

‎src/algorithms/sorting/insertion-sort/__test__/InsertionSort.test.js

+10-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import {
77
SortTester,
88
} from '../../SortTester';
99

10+
// Complexity constants.
11+
const SORTED_ARRAY_VISITING_COUNT = 20;
12+
const NOT_SORTED_ARRAY_VISITING_COUNT = 101;
13+
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 210;
14+
const EQUAL_ARRAY_VISITING_COUNT = 20;
15+
1016
describe('InsertionSort', () => {
1117
it('should sort array', () => {
1218
SortTester.testSort(InsertionSort);
@@ -21,42 +27,34 @@ describe('InsertionSort', () => {
2127
});
2228

2329
it('should visit EQUAL array element specified number of times', () => {
24-
const expectedNumberOfVisits = 20;
25-
2630
SortTester.testAlgorithmTimeComplexity(
2731
InsertionSort,
2832
equalArr,
29-
expectedNumberOfVisits,
33+
EQUAL_ARRAY_VISITING_COUNT,
3034
);
3135
});
3236

3337
it('should visit SORTED array element specified number of times', () => {
34-
const expectedNumberOfVisits = 20;
35-
3638
SortTester.testAlgorithmTimeComplexity(
3739
InsertionSort,
3840
sortedArr,
39-
expectedNumberOfVisits,
41+
SORTED_ARRAY_VISITING_COUNT,
4042
);
4143
});
4244

4345
it('should visit NOT SORTED array element specified number of times', () => {
44-
const expectedNumberOfVisits = 101;
45-
4646
SortTester.testAlgorithmTimeComplexity(
4747
InsertionSort,
4848
notSortedArr,
49-
expectedNumberOfVisits,
49+
NOT_SORTED_ARRAY_VISITING_COUNT,
5050
);
5151
});
5252

5353
it('should visit REVERSE SORTED array element specified number of times', () => {
54-
const expectedNumberOfVisits = 210;
55-
5654
SortTester.testAlgorithmTimeComplexity(
5755
InsertionSort,
5856
reverseArr,
59-
expectedNumberOfVisits,
57+
REVERSE_SORTED_ARRAY_VISITING_COUNT,
6058
);
6159
});
6260
});

‎src/algorithms/sorting/selection-sort/__test__/SelectionSort.test.js

+10-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import {
77
SortTester,
88
} from '../../SortTester';
99

10+
// Complexity constants.
11+
const SORTED_ARRAY_VISITING_COUNT = 209;
12+
const NOT_SORTED_ARRAY_VISITING_COUNT = 209;
13+
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 209;
14+
const EQUAL_ARRAY_VISITING_COUNT = 209;
15+
1016
describe('SelectionSort', () => {
1117
it('should sort array', () => {
1218
SortTester.testSort(SelectionSort);
@@ -17,42 +23,34 @@ describe('SelectionSort', () => {
1723
});
1824

1925
it('should visit EQUAL array element specified number of times', () => {
20-
const expectedNumberOfVisits = 209;
21-
2226
SortTester.testAlgorithmTimeComplexity(
2327
SelectionSort,
2428
equalArr,
25-
expectedNumberOfVisits,
29+
EQUAL_ARRAY_VISITING_COUNT,
2630
);
2731
});
2832

2933
it('should visit SORTED array element specified number of times', () => {
30-
const expectedNumberOfVisits = 209;
31-
3234
SortTester.testAlgorithmTimeComplexity(
3335
SelectionSort,
3436
sortedArr,
35-
expectedNumberOfVisits,
37+
SORTED_ARRAY_VISITING_COUNT,
3638
);
3739
});
3840

3941
it('should visit NOT SORTED array element specified number of times', () => {
40-
const expectedNumberOfVisits = 209;
41-
4242
SortTester.testAlgorithmTimeComplexity(
4343
SelectionSort,
4444
notSortedArr,
45-
expectedNumberOfVisits,
45+
NOT_SORTED_ARRAY_VISITING_COUNT,
4646
);
4747
});
4848

4949
it('should visit REVERSE SORTED array element specified number of times', () => {
50-
const expectedNumberOfVisits = 209;
51-
5250
SortTester.testAlgorithmTimeComplexity(
5351
SelectionSort,
5452
reverseArr,
55-
expectedNumberOfVisits,
53+
REVERSE_SORTED_ARRAY_VISITING_COUNT,
5654
);
5755
});
5856
});

‎src/data-structures/heap/MinHeap.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import Comparator from '../../utils/comparator/Comparator';
22

33
export default class MinHeap {
4-
constructor() {
4+
constructor(comparatorFunction) {
55
// Array representation of the heap.
66
this.heapContainer = [];
7-
this.compare = new Comparator();
7+
this.compare = new Comparator(comparatorFunction);
88
}
99

1010
static getLeftChildIndex(parentIndex) {
@@ -120,6 +120,10 @@ export default class MinHeap {
120120
}
121121
}
122122

123+
isEmpty() {
124+
return !this.heapContainer.length;
125+
}
126+
123127
toString() {
124128
return this.heapContainer.toString();
125129
}

‎src/data-structures/heap/__test__/MinHeap.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ describe('MinHeap', () => {
66

77
expect(minHeap).toBeDefined();
88
expect(minHeap.peek()).toBeNull();
9+
expect(minHeap.isEmpty()).toBeTruthy();
910
});
1011

1112
it('should add items to the heap and heapify it up', () => {
1213
const minHeap = new MinHeap();
1314

1415
minHeap.add(5);
16+
expect(minHeap.isEmpty()).toBeFalsy();
1517
expect(minHeap.peek()).toBe(5);
1618
expect(minHeap.toString()).toBe('5');
1719

0 commit comments

Comments
 (0)
Please sign in to comment.