Algorithmen und Datenstrukturen in TypeScript: Vom Anfänger zum Profi
Algorithmen und Datenstrukturen sind das Fundament, auf dem die gesamte moderne Softwareentwicklung aufbaut. Unabhängig davon, ob Sie ein Frontend mit React, ein Backend mit Node.js oder eine mobile App schreiben, ermöglicht ein tiefes Verständnis dieser Konzepte die Erstellung effizienter, skalierbarer und schneller Anwendungen. In diesem Artikel werden wir die wichtigsten Algorithmen und Datenstrukturen in TypeScript im Detail behandeln – einer Sprache, die die Flexibilität von JavaScript mit der Strenge statischer Typisierung kombiniert.
TypeScript ist ideal zum Erlernen von Algorithmen: Die strenge Typisierung hilft, Fehler bereits zur Kompilierzeit zu vermeiden, und die Unterstützung von Generics ermöglicht die Erstellung universeller und wiederverwendbarer Datenstrukturen. Wir beginnen mit einfachen Konzepten und gehen schrittweise zu komplexeren Themen über, wobei jeder Schritt von anschaulichen Codebeispielen begleitet wird.
1. Grundlegende Datenstrukturen: Stack und Queue
Stack und Queue sind grundlegende lineare Datenstrukturen, die überall verwendet werden: von der Verwaltung des Browserverlaufs bis zur Aufgabenplanung in Betriebssystemen. Betrachten wir ihre Implementierung in TypeScript.
Stack (LIFO – Last In, First Out)
Ein Stack funktioniert nach dem Prinzip "zuletzt herein – zuerst heraus". Die wichtigsten Operationen sind: push (Hinzufügen eines Elements) und pop (Entfernen des letzten Elements).
class Stack<T> { private items: T[] = [];
push(element: T): void { this.items.push(element); }
pop(): T | undefined { return this.items.pop(); }
peek(): T | undefined { return this.items[this.items.length - 1]; }
isEmpty(): boolean { return this.items.length === 0; }
size(): number { return this.items.length; }}
// Beispiel zur Verwendungconst stack = new Stack<number>();stack.push(1);stack.push(2);stack.push(3);console.log(stack.pop()); // 3console.log(stack.peek()); // 2Queue (FIFO – First In, First Out)
Eine Queue funktioniert nach dem Prinzip "zuerst herein – zuerst heraus". Die wichtigsten Operationen sind: enqueue (Hinzufügen am Ende) und dequeue (Entfernen vom Anfang).
class Queue<T> { private items: T[] = [];
enqueue(element: T): void { this.items.push(element); }
dequeue(): T | undefined { return this.items.shift(); }
front(): T | undefined { return this.items[0]; }
isEmpty(): boolean { return this.items.length === 0; }
size(): number { return this.items.length; }}
// Beispiel zur Verwendungconst queue = new Queue<string>();queue.enqueue("Erster");queue.enqueue("Zweiter");queue.enqueue("Dritter");console.log(queue.dequeue()); // "Erster"console.log(queue.front()); // "Zweiter"2. Suchalgorithmen: Lineare und Binäre Suche
Die Datensuche ist eine der häufigsten Operationen in der Programmierung. Wir betrachten zwei grundlegende Ansätze: die lineare Suche (einfach, aber langsam) und die binäre Suche (schnell, erfordert aber sortierte Daten).
Lineare Suche
Der Algorithmus überprüft nacheinander jedes Element des Arrays, bis er das gesuchte findet. Zeitkomplexität: O(n).
function linearSearch<T>(arr: T[], target: T): number { for (let i = 0; i < arr.length; i++) { if (arr[i] === target) { return i; // Gibt den Index des gefundenen Elements zurück } } return -1; // Element nicht gefunden}
// Beispielconst numbers = [10, 20, 30, 40, 50];console.log(linearSearch(numbers, 30)); // 2console.log(linearSearch(numbers, 60)); // -1Binäre Suche
Die binäre Suche funktioniert nur auf sortierten Arrays. Sie teilt das Array bei jedem Schritt in zwei Hälften und verwirft eine Hälfte