Introducción: ¿por qué estudiar algoritmos y estructuras de datos en Kotlin?
Kotlin es un lenguaje de programación moderno, conciso y seguro que se utiliza activamente para el desarrollo de Android, servicios backend e incluso aplicaciones de escritorio. Pero saber escribir código en Kotlin es solo la mitad del éxito. Para convertirte en un desarrollador realmente bueno, necesitas entender cómo funcionan los algoritmos y las estructuras de datos.
¿Por qué es necesario para un principiante? En primer lugar, conocer las estructuras básicas (listas, pilas, colas, tablas hash) ayuda a escribir código más eficiente y rápido. En segundo lugar, los algoritmos son la base para resolver problemas técnicos en las entrevistas. En tercer lugar, es simplemente interesante: empiezas a ver la lógica y las matemáticas detrás del código.
En este artículo, analizaremos los algoritmos y estructuras de datos clave en Kotlin desde cero. Todos los ejemplos serán simples, comprensibles y listos para ejecutar. ¡Vamos allá!
1. Estructuras de datos básicas en Kotlin
Arreglos y listas
En Kotlin hay dos tipos principales de colecciones: Array (tamaño fijo) y List (dinámica). Para la mayoría de las tareas, es más conveniente usar List.
fun main() { // Arreglo de tamaño fijo val numbersArray = arrayOf(1, 2, 3, 4, 5) println("Arreglo: ${numbersArray.joinToString()}")
// Lista mutable val mutableList = mutableListOf(10, 20, 30) mutableList.add(40) println("Lista después de agregar: $mutableList")
// Lista inmutable val immutableList = listOf(100, 200, 300) println("Lista inmutable: $immutableList")}Pila (Stack)
La pila funciona bajo el principio LIFO (Last In, First Out) — el último en entrar es el primero en salir. En Kotlin no hay una clase Stack incorporada, pero es fácil de implementar usando MutableList.
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(1) stack.push(2) stack.push(3)
println("Elemento superior: ${stack.peek()}") // 3 println("Extraemos: ${stack.pop()}") // 3 println("Ahora el superior: ${stack.peek()}") // 2}Cola (Queue)
La cola funciona bajo el principio FIFO (First In, First Out) — el primero en entrar es el primero en salir. En Kotlin, para esto es conveniente usar LinkedList de Java.
import java.util.LinkedList
class Queue<T> { private val elements = LinkedList<T>()
fun enqueue(item: T) = elements.add(item) fun dequeue(): T? = elements.poll() fun peek(): T? = elements.peek() fun isEmpty() = elements.isEmpty() fun size() = elements.size}
fun main() { val queue = Queue<String>() queue.enqueue("Primero") queue.enqueue("Segundo") queue.enqueue("Tercero")
println("Atendemos: ${queue.dequeue()}") // Primero println("Siguiente: ${queue.peek()}") // Segundo}2. Algoritmos de ordenamiento en Kotlin
Ordenamiento de burbuja (Bubble Sort)
Algoritmo simple pero lento. Adecuado para aprender, pero no para proyectos reales.
fun bubbleSort(arr: MutableList<Int>) { val n = arr.size for (i in 0 until n - 1) { for (j in 0 until n - i - 1) { if (arr[j] > arr[j + 1]) { val temp = arr[j] arr[j] = arr[j + 1] arr[j + 1] = temp } } }}
fun main() { val list = mutableListOf(64, 34, 25, 12, 22, 11, 90) bubbleSort(list) println("Ordenado con burbuja: $list")}