Add BubbleSort.

This commit is contained in:
Oleksii Trekhleb 2018-04-12 14:32:34 +03:00
parent 5320bfc7ec
commit 33963d8e08
5 changed files with 48 additions and 46 deletions

View File

@ -41,10 +41,10 @@ function initCallbacks(callbacks = {}) {
/** /**
* @param {Graph} graph * @param {Graph} graph
* @param {GraphVertex} startVertex * @param {GraphVertex} startVertex
* @param {Callbacks} [rawCallbacks] * @param {Callbacks} [originalCallbacks]
*/ */
export default function breadthFirstSearch(graph, startVertex, rawCallbacks) { export default function breadthFirstSearch(graph, startVertex, originalCallbacks) {
const callbacks = initCallbacks(rawCallbacks); const callbacks = initCallbacks(originalCallbacks);
const vertexQueue = new Queue(); const vertexQueue = new Queue();
// Do initial queue setup. // Do initial queue setup.

View File

@ -9,17 +9,17 @@ import Comparator from '../../utils/comparator/Comparator';
*/ */
export default class Sort { export default class Sort {
constructor(rawCallbacks) { constructor(originalCallbacks) {
this.callbacks = Sort.initSortingCallbacks(rawCallbacks); this.callbacks = Sort.initSortingCallbacks(originalCallbacks);
this.comparator = new Comparator(this.callbacks.compareCallback); this.comparator = new Comparator(this.callbacks.compareCallback);
} }
/** /**
* @param {SorterCallbacks} rawCallbacks * @param {SorterCallbacks} originalCallbacks
* @returns {SorterCallbacks} * @returns {SorterCallbacks}
*/ */
static initSortingCallbacks(rawCallbacks) { static initSortingCallbacks(originalCallbacks) {
const callbacks = rawCallbacks || {}; const callbacks = originalCallbacks || {};
const stubCallback = () => {}; const stubCallback = () => {};
callbacks.compareCallback = callbacks.compareCallback || undefined; callbacks.compareCallback = callbacks.compareCallback || undefined;

View File

@ -24,7 +24,6 @@ export class SortTester {
if (a.length === b.length) { if (a.length === b.length) {
return 0; return 0;
} }
return a.length < b.length ? -1 : 1; return a.length < b.length ? -1 : 1;
}, },
}; };
@ -36,4 +35,14 @@ export class SortTester {
expect(sorter.sort(['aa', 'a'])).toEqual(['a', 'aa']); expect(sorter.sort(['aa', 'a'])).toEqual(['a', 'aa']);
expect(sorter.sort(['bb', 'aa', 'c'])).toEqual(['c', 'bb', 'aa']); expect(sorter.sort(['bb', 'aa', 'c'])).toEqual(['c', 'bb', 'aa']);
} }
static testAlgorithmTimeComplexity(SortingClass, arrayToBeSorted, numberOfVisits) {
const visitingCallback = jest.fn();
const callbacks = { visitingCallback };
const sorter = new SortingClass(callbacks);
sorter.sort(arrayToBeSorted);
expect(visitingCallback).toHaveBeenCalledTimes(numberOfVisits);
}
} }

View File

@ -4,7 +4,8 @@ export default class BubbleSort extends Sort {
sort(initialArray) { sort(initialArray) {
// Flag that holds info about whether the swap has occur or not. // Flag that holds info about whether the swap has occur or not.
let swapped = false; let swapped = false;
const array = initialArray; // Clone original array to prevent its modification.
const array = initialArray.slice(0);
for (let i = 0; i < array.length; i += 1) { for (let i = 0; i < array.length; i += 1) {
swapped = false; swapped = false;

View File

@ -16,51 +16,43 @@ describe('BubbleSort', () => {
SortTester.testSortWithCustomComparator(BubbleSort); SortTester.testSortWithCustomComparator(BubbleSort);
}); });
it('should visit sorted array element specified number of times', () => { it('should visit EQUAL array element specified number of times', () => {
const visitingCallback = jest.fn(); const expectedNumberOfVisits = 19;
const callbacks = { visitingCallback }; SortTester.testAlgorithmTimeComplexity(
const sorter = new BubbleSort(callbacks); BubbleSort,
equalArr,
const arrayAfterSorting = sorter.sort(sortedArr); expectedNumberOfVisits,
);
expect(arrayAfterSorting).toEqual(sortedArr);
expect(visitingCallback).toHaveBeenCalledTimes(19);
}); });
it('should visit not-sorted array element specified number of times', () => { it('should visit SORTED array element specified number of times', () => {
const visitingCallback = jest.fn(); const expectedNumberOfVisits = 19;
const callbacks = { visitingCallback }; SortTester.testAlgorithmTimeComplexity(
const sorter = new BubbleSort(callbacks); BubbleSort,
sortedArr,
const arrayAfterSorting = sorter.sort(notSortedArr); expectedNumberOfVisits,
);
expect(arrayAfterSorting).toEqual(sortedArr);
expect(visitingCallback).toHaveBeenCalledTimes(19);
}); });
it('should visit equal array element specified number of times', () => { it('should visit NOT SORTED array element specified number of times', () => {
const visitingCallback = jest.fn(); const expectedNumberOfVisits = 266;
const callbacks = { visitingCallback }; SortTester.testAlgorithmTimeComplexity(
const sorter = new BubbleSort(callbacks); BubbleSort,
notSortedArr,
const arrayAfterSorting = sorter.sort(equalArr); expectedNumberOfVisits,
);
expect(arrayAfterSorting).toEqual(equalArr);
expect(visitingCallback).toHaveBeenCalledTimes(19);
}); });
it('should visit reverse sorted array element specified number of times', () => { it('should visit REVERSE SORTED array element specified number of times', () => {
const visitingCallback = jest.fn(); const expectedNumberOfVisits = 380;
const callbacks = { visitingCallback }; SortTester.testAlgorithmTimeComplexity(
const sorter = new BubbleSort(callbacks); BubbleSort,
reverseArr,
const arrayAfterSorting = sorter.sort(reverseArr); expectedNumberOfVisits,
);
expect(arrayAfterSorting).toEqual(sortedArr);
expect(visitingCallback).toHaveBeenCalledTimes(19);
}); });
}); });