Merge pull request 'feature/OneMoreSorting' (#9) from feature/OneMoreSorting into main
All checks were successful
Build & Push Frontend A / docker (push) Successful in 43s

Reviewed-on: #9
This commit was merged in pull request #9.
This commit is contained in:
2026-02-04 15:34:18 +01:00
5 changed files with 79 additions and 16 deletions

View File

@@ -6,4 +6,5 @@
static readonly BUBBLE_SORT_WIKI = 'https://de.wikipedia.org/wiki/Bubblesort'
static readonly QUICK_SORT_WIKI = 'https://de.wikipedia.org/wiki/Quicksort'
static readonly HEAP_SORT_WIKI = 'https://de.wikipedia.org/wiki/Heapsort'
static readonly SHAKE_SORT_WIKI = 'https://de.wikipedia.org/wiki/Shakersort'
}

View File

@@ -6,14 +6,13 @@ import {SortData, SortSnapshot} from '../sorting.models';
})
export class SortingService {
constructor() { }
private createSnapshot(array: SortData[]): SortSnapshot {
return {
array: array.map(item => ({ ...item }))
};
}
// --- BUBBLE SORT ---
bubbleSort(array: SortData[]): SortSnapshot[] {
const snapshots: SortSnapshot[] = [];
const arr = array.map(item => ({ ...item }));
@@ -25,7 +24,7 @@ export class SortingService {
for (let j = 0; j < n - i - 1; j++) {
arr[j].state = 'comparing';
arr[j + 1].state = 'comparing';
snapshots.push(this.createSnapshot(arr)); // Snapshot Vergleich
snapshots.push(this.createSnapshot(arr));
if (arr[j].value > arr[j + 1].value) {
const temp = arr[j].value;
@@ -48,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 }));
@@ -76,7 +128,7 @@ export class SortingService {
private partition(arr: SortData[], low: number, high: number, snapshots: SortSnapshot[]): number {
const pivot = arr[high];
arr[high].state = 'comparing'; // Pivot visualisieren
arr[high].state = 'comparing';
snapshots.push(this.createSnapshot(arr));
let i = (low - 1);
@@ -149,7 +201,6 @@ export class SortingService {
arr[largest].state = 'unsorted';
}
// Vergleich Rechts
if (r < n) {
arr[r].state = 'comparing';
arr[largest].state = 'comparing';

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();

View File

@@ -334,6 +334,7 @@
"BUBBLE_SORT_EXPLANATION":"vergleicht wiederholt benachbarte Elemente und tauscht sie, wenn sie in der falschen Reihenfolge stehen. Das größte Element \"blubbert\" dabei wie eine Luftblase ans Ende der Liste. Vorteil: Extrem einfach zu verstehen und zu implementieren; erkennt bereits sortierte Listen sehr schnell. Nachteil: Sehr ineffizient bei großen Listen (Laufzeit O(n²)). In der Praxis kaum genutzt.",
"QUICK_SORT_EXPLANATION": "folgt dem \"Teile und Herrsche\"-Prinzip. Ein \"Pivot\"-Element wird gewählt, und das Array wird in zwei Hälften geteilt: Elemente kleiner als das Pivot und Elemente größer als das Pivot. Vorteil: Im Durchschnitt einer der schnellsten Sortieralgorithmen (O(n log n)); benötigt keinen zusätzlichen Speicher (In-Place). Nachteil: Im schlechtesten Fall (Worst Case) langsam (O(n²)), wenn das Pivot ungünstig gewählt wird. Ist nicht stabil (ändert Reihenfolge gleicher Elemente).",
"HEAP_SORT_EXPLANATION": "organisiert die Daten zunächst in einer speziellen Baumstruktur (Binary Heap). Das größte Element (die Wurzel) wird entnommen und ans Ende sortiert, dann wird der Baum repariert. Vorteil: Garantiert eine schnelle Laufzeit von O(n log n), selbst im schlechtesten Fall. Benötigt fast keinen zusätzlichen Speicher. Nachteil: In der Praxis oft etwas langsamer als Quick Sort, da die Sprünge im Speicher (Heap-Struktur) den CPU-Cache schlechter nutzen.",
"COCKTAIL_SORT_EXPLANATION" : "(auch Shaker Sort) ist eine Erweiterung des Bubble Sort. Statt nur von links nach rechts zu gehen, wechselt er bei jedem Durchlauf die Richtung und schiebt abwechselnd das größte Element nach rechts und das kleinste nach links. Vorteil: Schneller als Bubble Sort, da kleine Elemente am Ende schneller nach vorne wandern (\"Schildkröten-Problem\" gelöst). Nachteil: Bleibt in der Laufzeitklasse O(n²), also für große Datenmengen ineffizient.",
"NOTE": "HINWEIS",
"DISCLAIMER": "Die Wahl des \"besten\" Sortieralgorithmus hängt stark von den Daten und den Rahmenbedingungen ab. In der Informatik betrachtet man oft drei Szenarien:",
"DISCLAIMER_1": "Best Case: Die Daten sind schon fast sortiert (hier glänzt z.B. Bubble Sort).",