Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wet-times-slide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"sortman": minor
---

feat: add ShakerSort algorithm and integrate into SortMan
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ console.log(sorted);
- Merge sort - `SortMan.merge`
- Quick sort - `SortMan.quick`
- Selection sort - `SortMan.selection`
- Shaker sort - `SortMan.shaker`
- Shell sort - `SortMan.shell`

# Options
Expand Down
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions src/Sort/ShakerSort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { swap } from "../utils/swap";
import { SortBase, type SortCoreElement } from "./SortBase";

export class ShakerSort extends SortBase {
private asc<T>(arr: SortCoreElement<T>, start: number, end: number) {
if (start < end) {
if (
(arr[start] as SortCoreElement<T>[number]).num >
(arr[start + 1] as SortCoreElement<T>[number]).num
) {
swap(start, start + 1, arr);
}
this.asc(arr, start + 1, end);
}
return arr;
}

private desc<T>(arr: SortCoreElement<T>, start: number, end: number) {
if (end > start) {
if (
(arr[end - 1] as SortCoreElement<T>[number]).num >
(arr[end] as SortCoreElement<T>[number]).num
) {
swap(end - 1, end, arr);
}
this.desc(arr, start, end - 1);
}
return arr;
}

public core<T>(content: SortCoreElement<T>): SortCoreElement<T> {
let arr = content.concat();
let start = 0;
let end = arr.length - 1;

while (true) {
arr = this.asc(arr, start, end);
end--;
if (start === end) {
break;
}
arr = this.desc(arr, start, end);
start++;
if (start === end) {
break;
}
}
return arr;
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ShellSort } from "./Sort/ShellSort";
import { BucketSort } from "./Sort/BucketSort";
import { CombSort } from "./Sort/CombSort";
import { GnomeSort } from "./Sort/GnomeSort";
import { ShakerSort } from "./Sort/ShakerSort";

import type { SortOptions } from "./Sort/SortBase";

Expand All @@ -23,6 +24,7 @@ export class SortMan {
public static readonly merge = new MergeSort();
public static readonly quick = new QuickSort();
public static readonly selection = new SelectionSort();
public static readonly shaker = new ShakerSort();
public static readonly shell = new ShellSort();

public static sort<T extends number>(arr: T[]): T[];
Expand Down
66 changes: 16 additions & 50 deletions tests/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { SortMan } from "../src/index";
import { randomString } from "../src/utils/random";
import { SortMan as TranspiledSortMan } from "../dist/index.cjs";

import type { Global } from "@jest/types";
import type { SortBase } from "../src/Sort/SortBase";
Expand All @@ -13,7 +12,6 @@ export type ObjectArrData = {

export type SortOptions = {
describe?: () => (blockName: Global.BlockNameLike, blockFn: Global.BlockFn) => void;
transpiled?: SortBase;
};

export type Sort = {
Expand Down Expand Up @@ -59,86 +57,54 @@ export const ignoreSorts = ["Default sort", "Bogo sort"] satisfies string[];
export const sorts: Sorts = [
{
name: "Default sort",
algorithm: SortMan as unknown as SortBase,
options: {
transpiled: TranspiledSortMan as unknown as SortBase
}
algorithm: SortMan as unknown as SortBase
},
{
name: "Bogo sort",
algorithm: SortMan.bogo,
options: {
transpiled: TranspiledSortMan.bogo as unknown as SortBase
}
algorithm: SortMan.bogo
},
{
name: "Bubble sort",
algorithm: SortMan.bubble,
options: {
transpiled: TranspiledSortMan.bubble as unknown as SortBase
}
algorithm: SortMan.bubble
},
{
name: "Quick sort",
algorithm: SortMan.quick,
options: {
transpiled: TranspiledSortMan.quick as unknown as SortBase
}
algorithm: SortMan.quick
},
{
name: "Merge sort",
algorithm: SortMan.merge,
options: {
transpiled: TranspiledSortMan.merge as unknown as SortBase
}
algorithm: SortMan.merge
},
{
name: "Insertion sort",
algorithm: SortMan.insertion,
options: {
transpiled: TranspiledSortMan.insertion as unknown as SortBase
}
algorithm: SortMan.insertion
},
{
name: "Selection sort",
algorithm: SortMan.selection,
options: {
transpiled: TranspiledSortMan.selection as unknown as SortBase
}
algorithm: SortMan.selection
},
{
name: "Heap sort",
algorithm: SortMan.heap,
options: {
transpiled: TranspiledSortMan.heap as unknown as SortBase
}
algorithm: SortMan.heap
},
{
name: "Shell sort",
algorithm: SortMan.shell,
options: {
transpiled: TranspiledSortMan.shell as unknown as SortBase
}
algorithm: SortMan.shell
},
{
name: "Bucket sort",
algorithm: SortMan.bucket,
options: {
transpiled: TranspiledSortMan.bucket as unknown as SortBase
}
algorithm: SortMan.bucket
},
{
name: "Comb sort",
algorithm: SortMan.comb,
options: {
transpiled: TranspiledSortMan.comb as unknown as SortBase
}
algorithm: SortMan.comb
},
{
name: "Gnome sort",
algorithm: SortMan.gnome,
options: {
transpiled: TranspiledSortMan.gnome as unknown as SortBase
}
algorithm: SortMan.gnome
},
{
name: "Shaker sort",
algorithm: SortMan.shaker
}
];