Skip to content

Commit 724d246

Browse files
authored
feat: add cycle sort implementation (TheAlgorithms#132)
* feat: add cycle sort implementation * feat: add cycle sort implementation - post review changes
1 parent 1cc8c98 commit 724d246

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353

5454
## Sorts
5555
* [Bubble Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/bubble_sort.ts)
56+
* [Cycle Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/cycle_sort.ts)
5657
* [Gnome Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/gnome_sort.ts)
5758
* [Insertion Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/insertion_sort.ts)
5859
* [Merge Sort](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/sorts/merge_sort.ts)

sorts/cycle_sort.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* @function cycleSort
3+
* @description Cycle sort is an in-place, unstable sorting algorithm, a comparison sort that is theoretically optimal in terms of the total number of writes to the original array, unlike any other in-place sorting algorithm. It is based on the idea that the permutation to be sorted can be factored into cycles, which can individually be rotated to give a sorted result.
4+
* @param {number[]}array - The input array
5+
* @return {number[]} - The sorted array.
6+
* @see [CycleSort] https://en.wikipedia.org/wiki/Cycle_sort
7+
* @example cycleSort([8, 3, 5, 1, 4, 2]) = [1, 2, 3, 4, 5, 8]
8+
*/
9+
10+
export const cycleSort = (array: number[]) => {
11+
for (let i: number = 0; i < array.length - 1; i++) {
12+
MoveCycle(array, i);
13+
}
14+
return array;
15+
};
16+
17+
function MoveCycle(array: number[], startIndex: number) : void {
18+
19+
let currentItem: number = array[startIndex];
20+
let nextChangeIndex: number = startIndex + CountSmallerItems(array, startIndex, currentItem);
21+
if(nextChangeIndex == startIndex)
22+
{
23+
return;
24+
}
25+
26+
nextChangeIndex = SkipDuplicates(array, nextChangeIndex, currentItem);
27+
28+
let tmp: number = array[nextChangeIndex];
29+
array[nextChangeIndex] = currentItem;
30+
currentItem = tmp;
31+
32+
while (nextChangeIndex != startIndex)
33+
{
34+
nextChangeIndex = startIndex + CountSmallerItems(array, startIndex, currentItem);
35+
nextChangeIndex = SkipDuplicates(array, nextChangeIndex, currentItem);
36+
37+
tmp = array[nextChangeIndex];
38+
array[nextChangeIndex] = currentItem;
39+
currentItem = tmp;
40+
}
41+
}
42+
43+
function CountSmallerItems(array: number[], startIndex: number, currentItem: number) : number{
44+
let elementsCount: number = 0;
45+
46+
for (let i: number = startIndex + 1; i < array.length; i++) {
47+
if(currentItem > array[i])
48+
{
49+
elementsCount++;
50+
}
51+
}
52+
53+
return elementsCount;
54+
}
55+
56+
function SkipDuplicates(array: number[], currentPosition: number, currentItem: number): number {
57+
while (array[currentPosition] == currentItem) {
58+
currentPosition++;
59+
}
60+
61+
return currentPosition;
62+
}
63+

sorts/test/cycle_sort.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { cycleSort } from "../cycle_sort";
2+
3+
describe("Cycle Sort", () => {
4+
it("should return the correct value for average case", () => {
5+
expect(cycleSort([1, 4, 2, 5, 9, 6, 3, 8, 10, 7])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
6+
});
7+
8+
it("should return the correct value for worst case", () => {
9+
expect(cycleSort([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
10+
});
11+
12+
it("should return the correct value for best case", () => {
13+
expect(cycleSort([1, 4, 2, 9, 5, 7, 3, 8, 10, 6])).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
14+
});
15+
});

0 commit comments

Comments
 (0)