diff --git a/.changeset/angry-dryers-open.md b/.changeset/angry-dryers-open.md new file mode 100644 index 0000000..bbcc9fa --- /dev/null +++ b/.changeset/angry-dryers-open.md @@ -0,0 +1,5 @@ +--- +"sortman": patch +--- + +Add description for bucket sort in readme diff --git a/.changeset/curly-buttons-build.md b/.changeset/curly-buttons-build.md new file mode 100644 index 0000000..8265508 --- /dev/null +++ b/.changeset/curly-buttons-build.md @@ -0,0 +1,5 @@ +--- +"sortman": patch +--- + +Fix merge sort's bug diff --git a/.changeset/fuzzy-adults-play.md b/.changeset/fuzzy-adults-play.md new file mode 100644 index 0000000..ebab36b --- /dev/null +++ b/.changeset/fuzzy-adults-play.md @@ -0,0 +1,5 @@ +--- +"sortman": patch +--- + +Change test func diff --git a/README.md b/README.md index 9189b41..9a6f750 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ console.log(sorted); - Quick sort - `SortMan.quick` - Selection sort - `SortMan.selection` - Shell sort - `SortMan.shell` +- Bucket sort - `SortMan.bucket` # Options diff --git a/src/Sort/MergeSort.ts b/src/Sort/MergeSort.ts index d5728b8..6d0555c 100644 --- a/src/Sort/MergeSort.ts +++ b/src/Sort/MergeSort.ts @@ -10,16 +10,27 @@ export class MergeSort extends SortBase { const right = this.core(content.slice(middle)); return (() => { const result: SortCoreElement = []; - do { - const leftElement = left[0] as SortCoreElement[number]; - const rightElement = right[0] as SortCoreElement[number]; - if (leftElement.num < rightElement.num) { - result.push(left.shift() as SortCoreElement[number]); + let i = 0; + let l = 0; + + while (i < left.length && l < right.length) { + const leftElement = left[i]; + const rightElement = right[l]; + + if (leftElement && rightElement && leftElement.num < rightElement.num) { + const element = left[i++]; + if (element) { + result.push(element); + } } else { - result.push(right.shift() as SortCoreElement[number]); + const element = right[l++]; + if (element) { + result.push(element); + } } - } while (left.length && right.length); - return result; + } + + return result.concat(left.slice(i)).concat(right.slice(l)); })(); } } diff --git a/tests/sort.test.ts b/tests/sort.test.ts index 5c6f9a5..d91ba61 100644 --- a/tests/sort.test.ts +++ b/tests/sort.test.ts @@ -2,25 +2,54 @@ import { describe, expect, test } from "@jest/globals"; import { ignoreSorts, numArrData, objectArrData, sorts } from "./utils"; import { sortCheck } from "../src/utils/array"; +function evalTest(originalData: number[], sortedData: number[], desc?: boolean): boolean { + const isSameArr = (() => { + const cache = new Map(); + + for (const element of originalData) { + const cachedData = cache.get(element); + if (cachedData) { + cache.set(element, cachedData + 1); + } else { + cache.set(element, 1); + } + } + + for (const [num, count] of cache.entries()) { + if (count !== sortedData.filter((value) => value === num).length) { + return false; + } + } + + return true; + })() satisfies boolean; + return sortCheck(sortedData, desc) && originalData.length === sortedData.length && isSameArr; +} + for (const { name, algorithm, options } of sorts) { if (!ignoreSorts.includes(name)) { describe(name, () => { describe("Normal test", () => { test("Number array", () => { const result = algorithm.sort(numArrData); - expect(sortCheck(result)).toBe(true); + expect(evalTest(numArrData, result)).toBe(true); }); test("Number array with options", () => { const result = algorithm.sort(numArrData, { func: (e) => e }); - expect(sortCheck(result)).toBe(true); + expect(evalTest(numArrData, result)).toBe(true); }); test("Object array", () => { const result = algorithm.sort(objectArrData, { func: (e) => e.num }); - expect(sortCheck(result.map(({ num }) => num))).toBe(true); + expect( + evalTest( + objectArrData.map(({ num }) => num), + result.map(({ num }) => num) + ) + ).toBe(true); }); }); describe("Option test", () => { @@ -28,7 +57,7 @@ for (const { name, algorithm, options } of sorts) { const result = algorithm.sort(numArrData, { desc: true }); - expect(sortCheck(result, true)).toBe(true); + expect(evalTest(numArrData, result, true)).toBe(true); }); }); if (options && options.describe) {