Algorithmen und Datenstrukturen in Kotlin: Von der Theorie zur Praxis
Kotlin ist eine moderne Programmiersprache, die die Prägnanz von Python mit der Leistungsfähigkeit von Java vereint. Um effizienten Code zu schreiben, müssen Sie verstehen, wie Algorithmen und Datenstrukturen funktionieren. In diesem Artikel werden wir Schlüsselkonzepte anhand von Kotlin-Beispielen erläutern, die Ihnen helfen, schnelle und zuverlässige Programme zu schreiben.
Das Material ist sowohl für Anfänger als auch für Entwickler nützlich, die ihr Wissen systematisieren möchten. Alle Beispiele können in der IntelliJ IDEA-Umgebung oder in einem Online-Compiler ausgeführt werden.
1. Grundlegende Datenstrukturen in Kotlin
Die Kotlin-Standardbibliothek bietet eine umfangreiche Sammlung von Datenstrukturen. Betrachten wir die wichtigsten.
Listen (List, MutableList)
Listen sind geordnete Sammlungen von Elementen. Kotlin unterscheidet zwischen veränderlichen und unveränderlichen Listen.
fun main() { // Unveränderliche Liste val fruits = listOf("Apfel", "Banane", "Orange") // Veränderliche Liste val numbers = mutableListOf(1, 2, 3) numbers.add(4) numbers.removeAt(1) println(fruits[0]) // Apfel println(numbers) // [1, 3, 4]}Mengen (Set, MutableSet)
Mengen speichern eindeutige Elemente. Sie sind nützlich, um Duplikate zu überprüfen.
fun main() { val uniqueNumbers = setOf(1, 2, 2, 3, 3, 3) println(uniqueNumbers) // [1, 2, 3] val mutableSet = mutableSetOf("a", "b") mutableSet.add("c") println(mutableSet.contains("b")) // true}Abbildungen (Map, MutableMap)
Abbildungen speichern Schlüssel-Wert-Paare. Ein Analogon zu einer Hashtabelle.
fun main() { val capitals = mapOf( "Russland" to "Moskau", "USA" to "Washington", "Frankreich" to "Paris" ) println(capitals["Russland"]) // Moskau // Veränderliche Map val scores = mutableMapOf("Ivan" to 85) scores["Maria"] = 92 scores["Ivan"] = 90}2. Implementierung klassischer Datenstrukturen
Manchmal reichen die Standardstrukturen nicht aus. Sehen wir uns an, wie man einen Stapel und eine Warteschlange manuell implementiert.
Stapel (Stack)
Ein Stapel arbeitet nach dem LIFO-Prinzip (Last In, First Out). Er wird in Parsern, Rückgängig-Funktionen und beim Durchlaufen von Graphen verwendet.
class Stack<T> { private val elements = mutableListOf<T>() fun push(item: T) = elements.add(item) fun pop(): T? = if (isEmpty()) null else elements.removeAt(elements.size - 1) fun peek(): T? = elements.lastOrNull() fun isEmpty() = elements.isEmpty() fun size() = elements.size}
fun main() { val stack = Stack<Int>() stack.push(10) stack.push(20) stack.push(30) println(stack.pop()) // 30 println(stack.peek()) // 20 println(stack.size()) // 2}Warteschlange (Queue)
Eine Warteschlange arbeitet nach dem FIFO-Prinzip (First In, First Out). Sie wird in Aufgabenverarbeitungssystemen verwendet.
class Queue<T> { private val elements = mutableListOf<T>() fun enqueue(item: T) = elements.add(item) fun dequeue(): T? = if (isEmpty()) null else elements.removeAt(0) fun peek(): T? = elements.firstOrNull() fun isEmpty() = elements.isEmpty()}
fun main() { val queue = Queue<String>() queue.enqueue("Aufgabe 1") queue.enqueue("Aufgabe 2") queue.enqueue("Aufgabe 3") println(queue.dequeue()) // Aufgabe 1 println(queue.peek()) // Aufgabe 2}3. Sortieralgorithmen in Kotlin
Sortieren ist eine grundlegende Operation. Sehen wir uns drei beliebte Algorithmen an.
QuickSort
Einer der effizientesten Algorithmen mit einer durchschnittlichen Komplexität von O(n log n).
fun quickSort(arr: IntArray, low: Int, high: Int) { if (low < high) { val pi = partition(arr, low, high) quickSort(arr, low, pi - 1) quick