Add Cocktail Sort algorithm and UI

Introduce Cocktail (Shaker) Sort to the sorting visualizer: implement cocktailSort and a helper switchValuesIfCorrect in the SortingService to generate snapshots for the animation. Add SHAKE_SORT_WIKI URL constant and a UI paragraph (with a link) plus German translation text for the algorithm explanation. Expose the new algorithm in the component (availableAlgorithms and switch handling). Also refactor the component to use Angular's inject() for SortingService and ChangeDetectorRef, tighten some typings (timeoutIds -> number[]), adjust default arraySize, and use const where appropriate.
This commit is contained in:
2026-02-04 15:33:51 +01:00
parent e1680426ad
commit 6f282a004b
5 changed files with 77 additions and 11 deletions

View File

@@ -12,6 +12,7 @@ export class SortingService {
};
}
// --- BUBBLE SORT ---
bubbleSort(array: SortData[]): SortSnapshot[] {
const snapshots: SortSnapshot[] = [];
const arr = array.map(item => ({ ...item }));
@@ -46,7 +47,60 @@ export class SortingService {
return snapshots;
}
// --- QUICK SORT ---
// --- COCKTAIL SORT ---
cocktailSort(array: SortData[]): SortSnapshot[] {
const snapshots: SortSnapshot[] = [];
const arr = array.map(item => ({ ...item }));
snapshots.push(this.createSnapshot(arr));
let start = -1;
let end = array.length-1;
let changed = false;
do {
changed = false;
start += 1;
for (let i = start; i < end; i++) {
changed = this.switchValuesIfCorrect(arr, i, snapshots, changed);
}
//DONE
if (!changed) {
break;
}
changed = false;
end -= 1;
for (let i = end; i >= start; i--) {
changed = this.switchValuesIfCorrect(arr, i, snapshots, changed);
}
} while (changed);
return snapshots;
}
private switchValuesIfCorrect(arr: { value: number; state: "sorted" | "comparing" | "unsorted" }[], i: number, snapshots: SortSnapshot[], changed: boolean) {
const firstValue = arr[i];
const secondValue = arr[i + 1];
firstValue.state = 'comparing';
secondValue.state = 'comparing';
snapshots.push(this.createSnapshot(arr));
if (firstValue.value > secondValue.value) {
const temp = firstValue.value;
firstValue.value = secondValue.value;
secondValue.value = temp;
changed = true;
}
firstValue.state = 'unsorted';
secondValue.state = 'unsorted';
snapshots.push(this.createSnapshot(arr));
return changed;
}
// --- QUICK SORT ---
quickSort(array: SortData[]): SortSnapshot[] {
const snapshots: SortSnapshot[] = [];
const arr = array.map(item => ({ ...item }));

View File

@@ -12,6 +12,11 @@
<a href="{{UrlConstants.BUBBLE_SORT_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>Cocktail Sort</strong> {{ 'SORTING.EXPLANATION.COCKTAIL_SORT_EXPLANATION' | translate}}
<a href="{{UrlConstants.SHAKE_SORT_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>Quick Sort</strong> {{ 'SORTING.EXPLANATION.QUICK_SORT_EXPLANATION' | translate}}
<a href="{{UrlConstants.QUICK_SORT_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>

View File

@@ -1,4 +1,4 @@
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {ChangeDetectorRef, Component, inject, OnInit} from '@angular/core';
import { CommonModule } from '@angular/common';
import {MatCardModule} from "@angular/material/card";
import {MatFormFieldModule} from "@angular/material/form-field";
@@ -20,26 +20,28 @@ import {UrlConstants} from '../../../constants/UrlConstants';
})
export class SortingComponent implements OnInit {
private readonly sortingService: SortingService = inject(SortingService);
private readonly cdr: ChangeDetectorRef = inject(ChangeDetectorRef);
readonly MAX_ARRAY_SIZE: number = 200;
readonly MIN_ARRAY_SIZE: number = 20;
private timeoutIds: any[] = [];
private timeoutIds: number[] = [];
sortArray: SortData[] = [];
unsortedArrayCopy: SortData[] = [];
arraySize: number = 100;
maxArrayValue: number = 100;
animationSpeed: number = 50; // Milliseconds per step
arraySize = 50;
maxArrayValue = 100;
animationSpeed = 50; // Milliseconds per step
// Placeholder for available sorting algorithms
availableAlgorithms: { name: string; value: string }[] = [
{ name: 'Bubble Sort', value: 'bubbleSort' },
{ name: 'Cocktail Sort', value: 'cocktailSort' },
{ name: 'Quick Sort', value: 'quickSort' },
{ name: 'Heap Sort', value: 'heapSort' },
];
selectedAlgorithm: string = this.availableAlgorithms[0].value;
executionTime: number = 0;
constructor(private readonly sortingService: SortingService, private readonly cdr: ChangeDetectorRef) { }
executionTime = 0;
ngOnInit(): void {
this.generateNewArray();
@@ -76,8 +78,8 @@ export class SortingComponent implements OnInit {
private resetSortState() {
for (let i = 0; i < this.sortArray.length; i++) {
let element = this.sortArray[i];
let unsortedElement = this.unsortedArrayCopy[i];
const element = this.sortArray[i];
const unsortedElement = this.unsortedArrayCopy[i];
element.value = unsortedElement.value;
element.state = 'unsorted';
}
@@ -98,6 +100,9 @@ export class SortingComponent implements OnInit {
case 'heapSort':
snapshots = this.sortingService.heapSort(this.sortArray);
break;
case 'cocktailSort':
snapshots = this.sortingService.cocktailSort(this.sortArray);
break;
}
const endTime = performance.now();