¡Las estructuras de datos es un tema tan amplio y tan hermoso, yo las aprendí por mi cuenta a medida que aprendía a programar y me interesaba por los algoritmos, este curso hacía falta!
Las usaremos mucho ya que son las que nos permitirán solucionar distintos problemas que nos encontremos como devs, es la forma en que podemos estructurar, almacenar y usar la data que tengamos.
Cada una cumple una función y resuelve un problema en particular, es nuestro deber y responsabilidad darles el mejor uso posible, y esto dependerá del problema que tengamos y como queramos abórdalo para solucionarlo. Esto lo podemos lograr entendiendo como funcionan cada estructura en su base conceptual
Ok para entender mejor esto es necesario que conozcas como gestiona JS en particular, el espacio en memoria, donde se almacena los valores de las variables, funciones y todo aquello que no sea un valor primitivo es en el memory heap (los valores primitivos se almacenan en el call stack dentro del scope en el que se encuentre las funciones o variables) y como se mandan a llamar es con el call stack, ya que aquí se guardan las referencias a las funciones con sus respectivos scopes locales.
Es una de las estructuras de datos mas básica y que probablemente ya hayas utilizado, es muy común que cuando no sepamos sobre este tema de Data Structures todo absolutamente todo lo metamos en un array y ya esta. Esto no suele ser buena practica ya que los Arrays no son la mejor de las soluciones en muchos casos.
Son una colleción de información, donde cada elemento (los valores que guardemos separados por coma) dentro del array tiene una posición, (Siempre iniciamos a contar en la posición 0).
En JS tenemos métodos que nos ayudan a manipularlos y recorrerlos.
También existen los Arrays dinámicos y estáticos. Por default en JS todos los Arrays son dinámicos.
A diferencia de otros lenguajes que definimos el tamaño del array desde el momento en el que lo declaramos, esto es para que se reserve el espacio en memoria de dicho array y no sea mutable. Reservando únicamente los slots correspondientes al tamaño del array.
Los strings no son una estructura de datos perse, pero se pueden comportar como un array, con la diferencia es que un string no es mutable, una vez declarado no se puede modificar dicho valor, se debe crear otra variable, o re asignar el valor.
En resumen: Los strings son inmutables es decir que una vez los definidos no podemos cambiar “letra por letra” si no que tendremos que tomar todos los items y comenzar a realizar la operación deseada también significa mayor esfuerzo de computo.
En JS esta es una estructura de datos que no viene creada como tal. Esta estructura de datos tiene distintos nombres según el lenguaje, en js son los objetos, aunque no es lo mismo que un hast table 100%
Las hash tienen distintos métodos, entre ellos están
El problema de las hash
La colisión: en ocasiones puede ocurrir que cuando pasemos por la hash function un key distinto a todos los key anteriores, nos puede retornar un hash repetido. Eso hace que tengamos dos elementos guardados con el mismo hash, y como te estas imaginando eso es un problema bastante feo y adivina, no hay manera de evitar esto.
Pero la colisión se puede tratar, y la manera de hacerlo es curiosamente con otra estructura de datos, las linked list (listas enlazada)
En resumen: Las hash tables se parecen a los objetos porque podemos guardar valores por llave, valor. Pero su principal diferencia es que genera un hash para cada llave valor. El único problema es que se puede generar un mismo hash, colisionando así con uno anterior.
Son un conjuntó de nodos, donde en cada nodo esta el valor que guardamos y también una referencia en memoria de donde esta el nodo siguiente.
Te dejo este articulo para que profundizes mas sobre las linked list en JS Mas sobre las linked list en JS
Pero pensemos en las Singly Linked List como un edificio con escaleras donde cada piso sería un Nodo. Si quisiera ir del piso 1 al piso 5, estoy obligado a pasar por los pisos 2, 3 y 4. Además siempre debo entrar por el primer piso.
Para recorrer una linked list tenemos que pasar por todos y cada uno de los nodos, y siempre desde la cabeza, entonces ya podemos ver que es un poco ineficiente para algunos casos ya que no podemos acceder al valor de un nodo de manera rápida solo como su índice o su key como si seria el caso en los arrays y las tablas de hash.
Sino que por el contrario debemos de recorrer cada uno de los nodos si o si hasta llegar al que nos interesa.
Una ventaja es que al tener direcciones de en donde está en siguiente nodo, no hace falta que estén en memoria continua, como los arrays, sino que estos pueden estar en cualquier parte de la memoria y simplemente se referencia la ubicación en memoria de los nodos.
El último nodo siempre tiene un puntero que no tiene una referencia en memoria, es null, esto es para que podamos agregar mas elementos a la linked list
O pila en español. Piensa en la pila como un conjunto de platos, apilados uno encima de otro, esta estructura de datos tiene un comportamiento tipo LIFO (last in, fisrt out)
O fila en español. Son bastante similar a las stacks, pero tiene un comportamiento distinto, El de esta es FIFO (First in, first out), como un fila de personas en un banco por ejemplo. La persona que llega primero tiene derecho a ser atendida antes que el ultimo.
Tenemos métodos que nos ayudan en el manejo de las Queue:
Consta de un único elemento raíz, que es de donde parten todos los hijos, y los hijos de estos, el termino correcto es que se genera una ramificación de datos.
Se compone de nodos y a partir del nodo raíz se empieza a ramificar todos los demás nodos.
Los nodos padres son aquellos de los cuales se desprendes otras ramas, las cuales serán sus hijos.
También tenemos las hojas del árbol (leafs) que son los nodos finales. El ultimo nodo de cada ramificación.
Los nodos hermanos son los nodos que provengan del mismo padre
Por ultimo tenemos los sub arboles, estos se forman en la ramificaciones que se vayan haciendo.
Este es otro tipo de árbol y lo que lo hace especial es que sus nodos se van multiplicando, también se conoce como árbol balanceado, ya que tiene la misma cantidad de nodos a ambos lados del árbol.
Tiene la misma estructura de un binary tree perfect o árbol balanceado pero se diferencia en algo y es que un nodo solo puede tener dos ramificaciones y estas a su vez siguen un patrón:
¿Esto en que nos ayuda? Bueno en mucho, ya que nos ayuda a buscar valores de manera mas rápida. Aplicando el algoritmo “divide and conquer” Este se aplica a la búsqueda binaria, justo lo como se llama este árbol. ¿Coincidencia? Para nada!
Los métodos que vemos en el curso son:
Son nodos interconectados entre si.
Hay distintas maneras de representar los grafos pero en el curso se ve de la siguiente manera: