Estructuras de datos disponibles en Java
Estructuras de datos disponibles en Java
LinkedList:
Una LinkedList (lista enlazada) es una estructura de datos que consiste en una secuencia de
nodos donde cada nodo contiene dos elementos:
Singly LinkedList (Lista Enlazada Simple): Cada nodo tiene un solo puntero que apunta al
siguiente nodo en la lista.
Doubly LinkedList (Lista Doble Enlazada): Cada nodo tiene dos punteros, uno que apunta al
nodo anterior y otro que apunta al nodo siguiente.
Funcionamiento:
Sin embargo, el acceso a un elemento en una posición arbitraria tiene un costo de O(n), ya
que es necesario recorrer la lista para encontrar el nodo deseado.
HashMap:
Un HashMap es una estructura de datos que implementa una tabla hash para almacenar
pares clave-valor. El funcionamiento de la estructura está basado en las siguientes
componentes:
Función hash: Convierte una clave en un índice dentro de un arreglo subyacente. La clave
puede ser de cualquier tipo, y la función hash traduce esa clave a un valor numérico.
Buckets (cubetas): Son posiciones dentro del arreglo. Cada cubeta puede contener
múltiples entradas (pares clave-valor) en caso de que ocurra una "colisión", que sucede
cuando dos claves diferentes se asignan al mismo índice debido a la función hash.
Funcionamiento:
Cuando se añade una clave, la función hash calcula el índice en el arreglo donde se
almacenará la clave y su valor asociado.
En caso de una colisión (dos claves que hash a la misma ubicación), se usa una estructura
auxiliar como una lista enlazada o, en versiones más recientes de Java, un árbol binario
(balanceado) para almacenar múltiples pares clave-valor en una sola cubeta.
Estructura subyacente:
ArrayList está basado en un arreglo dinámico, lo que significa que los elementos se
almacenan de manera contigua en memoria.
LinkedList está basado en nodos, donde cada nodo apunta al siguiente en una secuencia
(no contigua en memoria).
Acceso a elementos:
ArrayList permite acceso aleatorio O(1), ya que se puede acceder directamente a un índice
en el arreglo.
LinkedList requiere acceso secuencial O(n), porque para encontrar un elemento se debe
recorrer la lista desde el comienzo o el final.
Inserción y eliminación:
En LinkedList, insertar o eliminar en cualquier posición tiene un costo O(1), siempre que se
tenga una referencia al nodo correspondiente.
Uso de memoria:
ArrayList utiliza menos memoria por elemento, ya que sólo almacena los datos.
LinkedList usa más memoria, ya que además del dato, cada nodo debe almacenar dos
referencias (en el caso de una lista doblemente enlazada).
Propósito:
HashSet se utiliza para almacenar solo valores únicos, sin duplicados. No se almacena un
par clave-valor, solo el valor.
HashMap se utiliza para almacenar pares clave-valor. La clave debe ser única, pero los
valores pueden repetirse.
Implementación:
HashSet está implementado internamente usando un HashMap, donde las claves del
HashMap son los elementos del HashSet y los valores se asignan de forma predeterminada.
Métodos:
En HashSet, se puede agregar, eliminar y comprobar si un valor está presente.
Colisiones en HashSet:
Un HashSet maneja las colisiones mediante una tabla hash interna, que organiza los
elementos en "buckets". Cuando dos elementos tienen el mismo valor de hash, se
almacenan en el mismo bucket:
En versiones anteriores de Java, estos elementos en conflicto se manejaban con una lista
enlazada.
Desde Java 8, cuando una cubeta contiene muchos elementos (superando un umbral), la
lista enlazada se convierte en un árbol binario balanceado (generalmente un árbol rojo-
negro), lo que mejora la eficiencia de las búsquedas en casos de muchas colisiones.
Colisiones en HashMap:
El manejo de colisiones en HashMap es similar al de HashSet, ya que también usa una tabla
hash y buckets:
Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2009). Introduction to Algorithms.
MIT Press.