mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-07-06 17:44:08 +08:00
Add BubbleSort.
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
export const sortedArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
export const sortedArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
|
||||||
export const notSortedArray = [10, 5, 30, -1, 0, 0, 1, 2, -3, 2];
|
export const reverseArr = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
|
||||||
export const equalArray = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
export const notSortedArr = [15, 8, 5, 12, 10, 1, 16, 9, 11, 7, 20, 3, 2, 6, 17, 18, 4, 13, 14, 19];
|
||||||
|
export const equalArr = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||||
|
|
||||||
export class SortTester {
|
export class SortTester {
|
||||||
static testSort(SortingClass) {
|
static testSort(SortingClass) {
|
||||||
@ -11,9 +12,10 @@ export class SortTester {
|
|||||||
expect(sorter.sort([1, 2])).toEqual([1, 2]);
|
expect(sorter.sort([1, 2])).toEqual([1, 2]);
|
||||||
expect(sorter.sort([2, 1])).toEqual([1, 2]);
|
expect(sorter.sort([2, 1])).toEqual([1, 2]);
|
||||||
expect(sorter.sort([1, 1, 1])).toEqual([1, 1, 1]);
|
expect(sorter.sort([1, 1, 1])).toEqual([1, 1, 1]);
|
||||||
expect(sorter.sort(sortedArray)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
expect(sorter.sort(sortedArr)).toEqual(sortedArr);
|
||||||
expect(sorter.sort(notSortedArray)).toEqual([-3, -1, 0, 0, 1, 2, 2, 5, 10, 30]);
|
expect(sorter.sort(reverseArr)).toEqual(sortedArr);
|
||||||
expect(sorter.sort(equalArray)).toEqual([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
expect(sorter.sort(notSortedArr)).toEqual(sortedArr);
|
||||||
|
expect(sorter.sort(equalArr)).toEqual(equalArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static testSortWithCustomComparator(SortingClass) {
|
static testSortWithCustomComparator(SortingClass) {
|
||||||
|
@ -2,9 +2,13 @@ import Sort from '../Sort';
|
|||||||
|
|
||||||
export default class BubbleSort extends Sort {
|
export default class BubbleSort extends Sort {
|
||||||
sort(initialArray) {
|
sort(initialArray) {
|
||||||
|
// Flag that holds info about whether the swap has occur or not.
|
||||||
|
let swapped = false;
|
||||||
const array = initialArray;
|
const array = initialArray;
|
||||||
|
|
||||||
for (let i = 0; i < array.length; i += 1) {
|
for (let i = 0; i < array.length; i += 1) {
|
||||||
|
swapped = false;
|
||||||
|
|
||||||
for (let j = 0; j < array.length - 1; j += 1) {
|
for (let j = 0; j < array.length - 1; j += 1) {
|
||||||
// Call visiting callback.
|
// Call visiting callback.
|
||||||
this.callbacks.visitingCallback(array[j]);
|
this.callbacks.visitingCallback(array[j]);
|
||||||
@ -14,8 +18,17 @@ export default class BubbleSort extends Sort {
|
|||||||
const tmp = array[j + 1];
|
const tmp = array[j + 1];
|
||||||
array[j + 1] = array[j];
|
array[j + 1] = array[j];
|
||||||
array[j] = tmp;
|
array[j] = tmp;
|
||||||
|
|
||||||
|
// Register the swap.
|
||||||
|
swapped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there were no swaps then array is already sorted and there is
|
||||||
|
// no need to proceed.
|
||||||
|
if (!swapped) {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
import BubbleSort from '../BubbleSort';
|
||||||
|
import {
|
||||||
|
equalArr,
|
||||||
|
notSortedArr,
|
||||||
|
reverseArr,
|
||||||
|
sortedArr,
|
||||||
|
SortTester,
|
||||||
|
} from '../../SortTester';
|
||||||
|
|
||||||
|
describe('BubbleSort', () => {
|
||||||
|
it('should sort array', () => {
|
||||||
|
SortTester.testSort(BubbleSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sort array with custom comparator', () => {
|
||||||
|
SortTester.testSortWithCustomComparator(BubbleSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit sorted array element specified number of times', () => {
|
||||||
|
const visitingCallback = jest.fn();
|
||||||
|
|
||||||
|
const callbacks = { visitingCallback };
|
||||||
|
const sorter = new BubbleSort(callbacks);
|
||||||
|
|
||||||
|
const arrayAfterSorting = sorter.sort(sortedArr);
|
||||||
|
|
||||||
|
expect(arrayAfterSorting).toEqual(sortedArr);
|
||||||
|
expect(visitingCallback).toHaveBeenCalledTimes(19);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit not-sorted array element specified number of times', () => {
|
||||||
|
const visitingCallback = jest.fn();
|
||||||
|
|
||||||
|
const callbacks = { visitingCallback };
|
||||||
|
const sorter = new BubbleSort(callbacks);
|
||||||
|
|
||||||
|
const arrayAfterSorting = sorter.sort(notSortedArr);
|
||||||
|
|
||||||
|
expect(arrayAfterSorting).toEqual(sortedArr);
|
||||||
|
expect(visitingCallback).toHaveBeenCalledTimes(19);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit equal array element specified number of times', () => {
|
||||||
|
const visitingCallback = jest.fn();
|
||||||
|
|
||||||
|
const callbacks = { visitingCallback };
|
||||||
|
const sorter = new BubbleSort(callbacks);
|
||||||
|
|
||||||
|
const arrayAfterSorting = sorter.sort(equalArr);
|
||||||
|
|
||||||
|
expect(arrayAfterSorting).toEqual(equalArr);
|
||||||
|
expect(visitingCallback).toHaveBeenCalledTimes(19);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should visit reverse sorted array element specified number of times', () => {
|
||||||
|
const visitingCallback = jest.fn();
|
||||||
|
|
||||||
|
const callbacks = { visitingCallback };
|
||||||
|
const sorter = new BubbleSort(callbacks);
|
||||||
|
|
||||||
|
const arrayAfterSorting = sorter.sort(reverseArr);
|
||||||
|
|
||||||
|
expect(arrayAfterSorting).toEqual(sortedArr);
|
||||||
|
expect(visitingCallback).toHaveBeenCalledTimes(19);
|
||||||
|
});
|
||||||
|
});
|
@ -1,45 +0,0 @@
|
|||||||
import BubbleSort from '../BubbleSort';
|
|
||||||
import { equalArray, notSortedArray, sortedArray, SortTester } from '../../SortTester';
|
|
||||||
|
|
||||||
describe('bubbleSort', () => {
|
|
||||||
it('should sort array', () => {
|
|
||||||
SortTester.testSort(BubbleSort);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should sort array with custom comparator', () => {
|
|
||||||
SortTester.testSortWithCustomComparator(BubbleSort);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should visit sorted array element specified number of times', () => {
|
|
||||||
const visitingCallback = jest.fn();
|
|
||||||
|
|
||||||
const callbacks = { visitingCallback };
|
|
||||||
const sorter = new BubbleSort(callbacks);
|
|
||||||
|
|
||||||
sorter.sort(sortedArray);
|
|
||||||
|
|
||||||
expect(visitingCallback).toHaveBeenCalledTimes(90);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should visit not-sorted array element specified number of times', () => {
|
|
||||||
const visitingCallback = jest.fn();
|
|
||||||
|
|
||||||
const callbacks = { visitingCallback };
|
|
||||||
const sorter = new BubbleSort(callbacks);
|
|
||||||
|
|
||||||
sorter.sort(notSortedArray);
|
|
||||||
|
|
||||||
expect(visitingCallback).toHaveBeenCalledTimes(90);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should visit equal array element specified number of times', () => {
|
|
||||||
const visitingCallback = jest.fn();
|
|
||||||
|
|
||||||
const callbacks = { visitingCallback };
|
|
||||||
const sorter = new BubbleSort(callbacks);
|
|
||||||
|
|
||||||
sorter.sort(equalArray);
|
|
||||||
|
|
||||||
expect(visitingCallback).toHaveBeenCalledTimes(90);
|
|
||||||
});
|
|
||||||
});
|
|
Reference in New Issue
Block a user