Skip to content

Commit 923d141

Browse files
author
Oskar Widmark
committed
feat: heap sort
1 parent 851ddf2 commit 923d141

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

src/Options.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ const getAlgorithmOptionFields = (
2020
return ['base'];
2121
case SortName.CombSort:
2222
return ['shrinkFactor'];
23+
case SortName.Heapsort:
24+
return ['heapType'];
2325
default:
2426
return [];
2527
}
@@ -40,6 +42,7 @@ const ALGORITHM_OPTION_LABELS: Record<keyof AlgorithmOptions, string> = {
4042
type: 'Type',
4143
base: 'Base',
4244
shrinkFactor: 'Shrink Factor',
45+
heapType: 'Heap Type',
4346
};
4447

4548
const ALGORITHM_OPTION_TEXT_FIELD_TYPES: Record<
@@ -49,6 +52,7 @@ const ALGORITHM_OPTION_TEXT_FIELD_TYPES: Record<
4952
type: 'select',
5053
base: 'number',
5154
shrinkFactor: 'number',
55+
heapType: 'select',
5256
};
5357

5458
const ALGORITHM_OPTION_VALUES: Record<
@@ -58,6 +62,7 @@ const ALGORITHM_OPTION_VALUES: Record<
5862
type: ['iterative', 'recursive'],
5963
base: [],
6064
shrinkFactor: [],
65+
heapType: ['max', 'min'],
6166
};
6267

6368
const ALGORITHM_OPTION_VALUE_LABELS: Record<
@@ -66,6 +71,8 @@ const ALGORITHM_OPTION_VALUE_LABELS: Record<
6671
> = {
6772
iterative: 'Iterative',
6873
recursive: 'Recursive',
74+
max: 'Max Heap',
75+
min: 'Min Heap',
6976
};
7077

7178
interface OptionsProps {

src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const DEFAULT_ALGORITHM_OPTIONS: AlgorithmOptions = {
1414
type: 'iterative',
1515
base: 4,
1616
shrinkFactor: 1.3,
17+
heapType: 'max',
1718
};
1819
export const DEFAULT_SOUND_VOLUME = 50;
1920
export const DEFAULT_SOUND_TYPE = 'triangle';

src/sorting-algorithms.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export class SortingAlgorithms {
2222
[SortName.BitonicSort]: this.bitonicSort,
2323
[SortName.BullySort]: this.bullySort,
2424
[SortName.AverageSort]: this.averageSort,
25+
[SortName.Heapsort]: this.heapsort,
2526
// 'Bully Sort 2': this.bullySort2,
2627
};
2728

@@ -572,4 +573,66 @@ public async mergeSort(arr, start, end){
572573
await this._averageSort(arr, start, mid);
573574
await this._averageSort(arr, mid, end);
574575
}
576+
577+
public async heapsort(arr: SortValue[], options: AlgorithmOptions) {
578+
switch (options.heapType) {
579+
case 'min':
580+
return await this.minHeapsort(arr);
581+
case 'max':
582+
return await this.maxHeapsort(arr);
583+
}
584+
}
585+
586+
private async minHeapsort(arr: SortValue[]) {
587+
for (let i = Math.ceil(arr.length / 2) + 1; i < arr.length; i++) {
588+
await this.minHeapify(arr, 0, i);
589+
}
590+
for (let i = 0; i < arr.length; i++) {
591+
await this.drawAndSwap(arr, arr.length - 1, i);
592+
await this.minHeapify(arr, i, arr.length - 1);
593+
}
594+
}
595+
596+
private async maxHeapsort(arr: SortValue[]) {
597+
for (let i = Math.floor(arr.length / 2) - 1; i >= 0; i--) {
598+
await this.maxHeapify(arr, arr.length, i);
599+
}
600+
for (let i = arr.length - 1; i > 0; i--) {
601+
await this.drawAndSwap(arr, 0, i);
602+
await this.maxHeapify(arr, i, 0);
603+
}
604+
}
605+
606+
// This a reversed heap, with the smallest element at the last index
607+
private async minHeapify(arr: SortValue[], n: number, i: number) {
608+
let smallestIndex = i;
609+
const left = arr.length - 1 - (2 * (arr.length - 1 - i) + 2);
610+
const right = arr.length - 1 - (2 * (arr.length - 1 - i) + 1);
611+
if (left > n && (await this.compare(arr, smallestIndex, '>', left))) {
612+
smallestIndex = left;
613+
}
614+
if (right > n && (await this.compare(arr, smallestIndex, '>', right))) {
615+
smallestIndex = right;
616+
}
617+
if (smallestIndex !== i) {
618+
await this.drawAndSwap(arr, i, smallestIndex);
619+
await this.minHeapify(arr, n, smallestIndex);
620+
}
621+
}
622+
623+
private async maxHeapify(arr: SortValue[], n: number, i: number) {
624+
let largestIndex = i;
625+
const left = 2 * i + 1;
626+
const right = 2 * i + 2;
627+
if (left < n && (await this.compare(arr, left, '>', largestIndex))) {
628+
largestIndex = left;
629+
}
630+
if (right < n && (await this.compare(arr, right, '>', largestIndex))) {
631+
largestIndex = right;
632+
}
633+
if (largestIndex !== i) {
634+
await this.drawAndSwap(arr, i, largestIndex);
635+
await this.maxHeapify(arr, n, largestIndex);
636+
}
637+
}
575638
}

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export enum SortName {
1313
BitonicSort = 'Bitonic Sort',
1414
BullySort = 'Bully Sort',
1515
AverageSort = 'Average Sort',
16+
Heapsort = 'Heapsort',
1617
}
1718

1819
export type SortAlgorithm = (
@@ -26,6 +27,7 @@ export type AlgorithmOptions = {
2627
type: 'iterative' | 'recursive';
2728
base: number;
2829
shrinkFactor: number;
30+
heapType: 'max' | 'min';
2931
};
3032

3133
export enum ResetPreset {

src/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export const sortNameToSortType: Record<SortName, string> = {
5959
[SortName.BitonicSort]: SortType.Comparison,
6060
[SortName.BullySort]: SortType.Comparison,
6161
[SortName.AverageSort]: SortType.Comparison,
62+
[SortName.Heapsort]: SortType.Comparison,
6263
};
6364

6465
// something that sounds good

0 commit comments

Comments
 (0)