Estoy aprendiendo estructuras de datos en Java. ¿Cómo puedo mejorarlo?

Impleméntelos. La implementación es la razón por la cual los cursos que enseñan estructuras de datos generalmente se enseñan como “Estructuras de datos y algoritmos “. ¿De qué sirven las listas enlazadas o un árbol binario si no puede, por ejemplo, encontrar el valor máximo almacenado por un nodo en general?

También debe comprender cómo estas estructuras de datos se almacenan realmente en la memoria. Hay muchas cosas específicas de implementación de JVM (punto de acceso) sobre cómo se maneja realmente la memoria.

La máxima eficiencia con las estructuras de datos a menudo también se reduce a patrones de optimización. Por ejemplo, localidad de datos. Esta es la motivación detrás de los grupos de memoria. Si desea crear y destruir rápidamente una gran cantidad de objetos, debe colocarlos lo más cerca posible para que, cuando acceda a estos objetos, su patrón de acceso a la memoria haga menos trabajo para obtener el siguiente elemento. Y, además de eso, podrías destruir todos estos objetos mucho más rápido. Este tipo de diseño de almacenamiento de estructura de datos se presta a patrones de optimización tales como acceso secuencial (que es más rápido que, digamos, acceso “aleatorio” * en el montón), cachés de CPU, captación previa, etc.

* aleatorio: me refiero a aleatorio: usted no tiene control de dónde se asignan realmente las asignaciones dinámicas en el montón. Entonces, iterar cosas en el montón, como una lista vinculada, podría significar que el primer nodo está en la dirección 45, el segundo elemento está en la dirección 999 y el tercero está en la dirección 110; iterando esto secuencialmente, en términos del siguiente nodo no se presta a la optimización. Esta es la razón por la cual las personas implementan grupos de memoria, como he dicho, pero también probablemente por qué muchas compañías han implementado sus propias versiones de malloc / free from libc.

Otra cosa, increíblemente útil, sería mirar más allá de las abstracciones . Por ejemplo, la programación orientada a objetos es excelente, pero debe comprender cómo se asignan realmente estos objetos y cómo funcionan realmente los métodos. Por ejemplo, en OOP, a los métodos de clase se les pasa implícitamente una referencia a sí mismos (eso es lo que es, esto, en este contexto, es la ubicación de la estructura de datos; por ejemplo, la ubicación del primer elemento de la). Esto se debe a que los datos pueden diferir, pero la funcionalidad del método no debería en realidad: si tenemos 50 objetos del mismo tipo, ¿realmente vamos a asignar todos sus métodos asociados 50 veces? Eso sería un desperdicio ya que serían lo mismo. Por lo tanto, asigne 50 objetos y utilizarán los mismos métodos pasándose una referencia a sí mismo como primer parámetro implícitamente.

Aquí hay un ejemplo:

car.driveForward (4);
en realidad se convierte en:
driveForward (& car, 4);

Es posible que no entienda esa sintaxis ya que es la sintaxis de referencia de C / C ++, algo con lo que nunca tendrá que lidiar en Java (ya que, por supuesto, está administrado).

Realmente recomiendo C para aprender estructuras de datos y algoritmos, ya que hay menos abstracciones y te dará una mejor comprensión de cómo funcionan realmente las abstracciones de lenguaje de nivel superior. Esto sucede a menudo en el momento en que bajas de nivel. En un minuto estará asignando un objeto en Java y suponiendo que vaya al montón y que el recolector de basura lo libere cuando esté fuera del alcance (técnicamente, la JVM puede elegir asignar en la pila un objeto pequeño, irrelevante) . A continuación, podría usar C y tomar decisiones conscientes sobre si asignar su estructura en la pila o el montón y tener que liberarlos explícitamente. Luego, podría ir más allá del ensamblaje y asignar conscientemente en la pila restando del puntero de la pila y haciendo una referencia adecuada de los elementos en la pila al pasarlos a subrutinas por cualquier convención de llamada que esté utilizando. Todo se reduce a abstracciones. Puede implementar la estructura de datos en muchos idiomas, por lo que la manipulación algorítmica (haciendo uso de esta estructura de datos) de manera eficiente es increíblemente importante. Si su comprensión de algo se aprende de una abstracción, es poco probable que su comprensión sea sólida y esto puede socavar más intentos de aprender otras cosas.

tl; dr: impleméntelos y comprenda algoritmos eficientes para manipularlos realmente.

En cuanto a aprender realmente estas cosas, recomiendo siempre dibujar la estructura de datos junto con partes que muestren cosas comunes que podría hacer con ellas. Por ejemplo, es fácil enseñar a insertar un nodo en el medio de una lista vinculada si dibuja el nuevo nodo y actualiza las flechas de los nodos anteriores y siguientes para que ahora apunten a este nuevo nodo. Confíe en mí cuando le diga, si estos diagramas visuales se expresan claramente (y usted es un aprendiz visual), los recordará cada vez que piense en implementar uno (incluso puede caer en la tentación de dibujarlo nuevamente como un pequeño resumen).

En general, siga con Java, pero creo que C es fundamental para que todos los programadores sean honestos; especialmente para estructuras de datos y algoritmos, y también lo hacen la mayoría de las unidades.

Creo que es mucho más fácil aprender las estructuras de datos en el plano C. Para que pueda centrarse en el algoritmo, no en la complejidad del lenguaje, en mi opinión.