Elección del lenguaje de programación para el aprendizaje de estructuras de datos y algoritmos [cerrado]

79

¿En qué lenguaje de programación recomendarías aprender sobre estructuras de datos y algoritmos ?

Considerando lo siguiente:

  • Experiencia personal
  • Funciones de idioma (punteros, OO, etc.)
  • Idoneidad para aprender los conceptos de DS & A

Pregunto porque hay algunos libros que son independientes del lenguaje de programación (escritos desde una perspectiva matemática y usan pseudocódigo). Si aprendo de uno de estos, me gustaría elegir un lenguaje de programación para codificar y ejecutar los algoritmos.

Luego, hay otros libros que introducen conceptos de DS & A con ejemplos escritos en un idioma de programación en particular, y me gustaría codificar estos algoritmos también, por lo que, hasta cierto punto, el idioma también elige el libro.

De cualquier manera, tengo que elegir un idioma y prefiero ceñirme a uno en todo momento. Dejando de lado las preferencias lingüísticas personales, ¿cuál es mejor para este propósito?

bguiz
fuente
No hay forma posible de responder a esta pregunta excepto en lo específico, y eso necesita más información.
David Thornley
@David Thornley: Entiendo que es un poco abierto, ¡pero ha obtenido muchas respuestas realmente geniales!
bguiz
Hay mucho ruido y pocas nueces sobre la eficiencia energética (solía ser: tiempo) de los algoritmos y las estructuras de datos: si desea medir esto, busque sistemas en los que se puedan obtener (y fácilmente) números significativos de forma reproducible.
greybeard

Respuestas:

88

La respuesta a esta pregunta depende exactamente de lo que quieras aprender.

Python y Ruby

A menudo se sugieren lenguajes de alto nivel como Python y Ruby porque son de alto nivel y la sintaxis es bastante legible. Sin embargo, todos estos lenguajes tienen abstracciones para las estructuras de datos comunes. No hay nada que le impida implementar sus propias versiones como ejercicio de aprendizaje, pero es posible que descubra que está construyendo estructuras de datos de alto nivel sobre otras estructuras de datos de alto nivel, lo que no es necesariamente útil.

Además, Ruby y Python son lenguajes de tipado dinámico. Esto puede ser bueno, pero también puede ser confuso para el principiante y puede ser más difícil (inicialmente) detectar errores, ya que normalmente no serán evidentes hasta el tiempo de ejecución.

C

C está en el otro extremo. Es bueno si desea aprender detalles de muy bajo nivel, como cómo se administra la memoria, pero la administración de la memoria de repente es una consideración importante, como en el uso correcto de malloc () / free (). Eso puede distraer. Además, C no está orientado a objetos. Eso no es malo, pero simplemente vale la pena señalarlo.

C ++

Se ha mencionado C ++. Como dije en el comentario, creo que esta es una elección terrible . C ++ es horriblemente complicado incluso en un uso simple y tiene una cantidad ridícula de "trampas". Además, C ++ no tiene una clase base común. Esto es importante porque las estructuras de datos como las tablas hash dependen de que haya una clase base común. Podría implementar una versión para una clase base nominal, pero es un poco menos útil.

Java

También se ha mencionado Java. A muchas personas les gusta odiar Java y es cierto que el lenguaje es extremadamente detallado y carece de algunas de las características del lenguaje más modernas (por ejemplo, cierres), pero nada de eso realmente importa. Java tiene un tipo estático y tiene recolección de basura. Esto significa que el compilador de Java detectará muchos errores que los lenguajes tipados dinámicamente no (hasta el tiempo de ejecución) y no hay que lidiar con las fallas de segmentación (lo que no quiere decir que no pueda perder memoria en Java; obviamente, puede). Creo que Java es una buena elección.

C#

C # el lenguaje es como una versión más moderna de Java. Como Java, es un lenguaje compilado intermedio administrado (recolectado de basura) que se ejecuta en una máquina virtual. Todos los demás lenguajes enumerados aquí, aparte de C / C ++, también se ejecutan en una máquina virtual, pero Python, Ruby, etc. se interpretan directamente en lugar de compilarse en un código de bytes.

Básicamente, C # tiene los mismos pros y contras que Java.

Haskell (etc.)

Por último, tienes lenguajes funcionales: Haskell, OCaml, Scheme / Lisp, Clojure, F #, etc. Estos piensan en todos los problemas de una manera muy diferente y vale la pena aprenderlos en algún momento, pero nuevamente todo se reduce a lo que quieres aprender: programación funcional o estructuras de datos? Me limitaría a aprender una cosa a la vez en lugar de confundir el tema. Si aprende un lenguaje funcional en algún momento (lo que recomendaría), Haskell es una buena opción y segura.

Mi consejo

Elija Java o C #. Ambos tienen IDE excelentes y gratuitos (Eclipse, Netbeans e IntelliJ Community Edition para Java, Visual Studio Express para C #, Visual Studio community edition) que facilitan la escritura y ejecución de código. Si no usa una estructura de datos nativa más compleja que una matriz y cualquier objeto que usted mismo escriba, aprenderá básicamente lo mismo que en C / C ++ pero sin tener que administrar la memoria.

Permítanme explicar: una tabla hash extensible debe cambiar de tamaño si se agregan suficientes elementos. En cualquier implementación, eso significará hacer algo como duplicar el tamaño de la estructura de datos de respaldo (generalmente una matriz) y copiar los elementos existentes. La implementación es básicamente la misma en todos los lenguajes imperativos, pero en C / C ++ tienes que lidiar con fallas de segmentación cuando no asignas o desasignas algo correctamente.

Python o Ruby (realmente no importa cuál) sería mi próxima opción (y muy cerca de las otras dos) solo porque la escritura dinámica podría ser problemática al principio.

cletus
fuente
1
@cletus: ¡Gracias por la respuesta tan bien razonada! ¿Qué libro de DS&A / otro material de instrucción recomendaría (para Java o Python)?
bguiz
3
@bguiz, es posible que desee hacer una pregunta separada al respecto. Hay varias preguntas sobre este tema para referirse a stackoverflow.com/search?q=book+data+structures+algoritms . Puede refinar eso agregando [java] o [python] a la búsqueda.
cletus
2
NO usaría Java y C # principalmente debido a la estricta orientación OO que es simplemente innecesaria para esto. Además: ¿a quién le importa escribir código genérico cuando el punto es aprender la estructura de datos? En mi opinión, o eliges un lenguaje de scripting (Python) y te enfocas en el de alto nivel o eliges un lenguaje de bajo nivel C / C ++ e intentas ver cómo se implementa a nivel de máquina. Parar en el medio no parece que valga la pena.
Matthieu M.
3
¿Python no se compila primero en bytecode? Novedades para mí: docs.python.org/release/2.5.2/lib/bytecodes.html
Adam Crossland
Esto no tiene sentido: "Esto es importante porque las estructuras de datos como las tablas hash dependen de que haya una clase base común". Las tablas hash dependen de que los elementos sean hash, pero los detalles de cómo esto se puede implementar en un lenguaje de programación son irrelevantes en la definición abstracta de una estructura de datos.
pyon
45

Recomendaría Javaprincipalmente porque:

  • recolección de basura
  • referencias
  • ricas colecciones

EDITAR: Votantes en contra, expliquen.

codaddict
fuente
3
¿Por qué todos votan en contra?
Mantas Vidutis
19
Creo que rechazar esto porque no te gusta Java (que parece estar sucediendo) es irresponsable. Puede que no le guste Java, pero es lo suficientemente simple como para usarlo como lenguaje de aprendizaje. Entonces +1 de mi parte.
cletus
7
+1. No es mi elección, pero en realidad no es terrible. La puntuación de votos es como sugirió COBOL.
Rob Lachlan
4
+1 porque para un principiante: 1. Exactamente, no tiene que preocuparse por la asignación de memoria / desbloqueo (al menos para programas pequeños). En su lugar, podría concentrarse en lo que tiene que aprender por el momento. 2. Sí, sin punteros furtivos o punteros a punteros. No me malinterpretes, me encanta C ++. 3. Las colecciones en Java son probablemente el conjunto de estructuras de datos más refinado que he visto. Realmente deberían estar en el diccionario bajo estructuras de datos. :)
crunchdog
9
Si no entiende cómo hacer su propia gestión de recursos, no ha aprendido mucho sobre estructuras de datos.
Alan
29

En mi opinión, C sería el mejor lenguaje para aprender estructuras de datos y algoritmos porque te obligará a escribir el tuyo propio. Lo obligará a comprender los punteros, la asignación de memoria dinámica y las implementaciones detrás de las estructuras de datos populares como listas vinculadas, tablas hash, etc. Muchas de las cuales son cosas que puede dar por sentado en lenguajes de nivel superior (Java, C #, etc. ).

Taylor Leese
fuente
11
Los punteros y la asignación de memoria dinámica no le enseñan nada acerca de las estructuras de datos y los algoritmos, pero obstaculizan seriamente lo que puede esperar lograr.
JD
1
Estoy de acuerdo. Después de tratar con docenas de lenguajes diferentes, y de haber aprendido primero uno de nivel superior y altamente abstracto, fue un dolor cuando decidí aprender C / C ++ y de repente tuve que lidiar con muchas cosas que nunca me explicaron. antes de. Aprender C primero (no C ++) es una excelente opción porque le expone cómo funciona realmente la máquina y tiene todas las limitaciones que obligaron a crear estructuras de datos en primer lugar. Todo lo que el lenguaje te da son funciones (para algoritmos) y estructuras (para estructuras de datos). La brecha entre la teoría y el lenguaje es realmente pequeña.
Rafael Beckel
17

Pythones genial. Fácil de leer, con todas las funciones. Si va a trabajar con pseudocódigo, Python le resultará bastante familiar.

Python ya es el lenguaje de algoritmos preferido en UC Irvine , donde se describe así:
" Python representa un lenguaje orientado a algoritmos que ha sido muy necesario en la educación. Las ventajas de Python incluyen su sintaxis similar a un libro de texto y su interactividad que fomenta la experimentación . "

Python también funciona de manera amigable para principiantes con Gato , una herramienta para hacer gráficos. Aprender algoritmos y estructuras de datos es una de las principales cosas que puede ayudar al hacerse visual, algo que Gato hace que sea fácil de hacer (sin aprender bibliotecas de gráficos complejas)

Mantas Vidutis
fuente
@mvid: ¿Recomendarías algún libro de DS & A basado en Python?
bguiz
1
@bguiz: Aunque no lo he leído personalmente, existe este libro electrónico gratuito que se enfoca en algoritmos y estructuras de datos usando OO en Python: brpreiss.com/books/opus7
Mantas Vidutis
Python solo es excelente si considera que la codificación con espacios en blanco como delimitador es increíble
Woot4Moo
¡El espacio en blanco como delimitador ES increíble!
Marcel Valdez Orozco
Tengo una aversión personal por Python debido a su uso sintáctico de sangrías. Encuentro que es más difícil encontrar errores tontos debido a la desalineación de lo que sería para la sintaxis basada en llaves y demás, compatible con una alineación adicional tipo nroff.
Michael
13

Si el propósito es solo aprender sobre estructuras de datos y algoritmos , diría JavaScript. Puede ejecutar su código en un navegador. Tiene un manejo de objetos muy flexible y puede enfocarse completamente en las estructuras de datos y algoritmos y no en la administración de la memoria, construcciones de lenguaje u otras cosas que desviarán el enfoque de la informática real que está aprendiendo.

La ventaja también es que puede visualizar fácilmente varias estructuras de datos utilizando el navegador para representar gráficos y árboles utilizando DOM y Canvas.

Los cursos de informática a lo largo de los años tienden a cambiar el idioma en el que se imparte la asignatura, simplemente porque han llegado nuevas y mejores implementaciones de idiomas que facilitan el aprendizaje, lo que hace que sea más fácil concentrarse en el problema real.

Ernelli
fuente
+1 porque JavaScript permite aprender programación funcional fácilmente y con la amplia aplicabilidad de poder desarrollar aplicaciones web con él.
Dan Dascalescu
Muy cierto. Pruebo mi código en el fragmento de herramientas de desarrollo. Además, puedo escribir de manera similar mis propias estructuras de datos en él. No hay una lista vinculada ni ninguna otra estructura incorporada. Todo es solo objeto. A menos que esté haciendo programación competitiva, funciona para aprender la búsqueda binaria, trie y todos los demás conceptos. ¿No?
HalfWebDev
totalmente de acuerdo, vamos a centrarnos en la lógica sin mucha ceremonia y sintaxis básica.
jtroconisa
8

Si quieres tomar el camino de menor resistencia, entonces Python. Tendrá la cantidad mínima de placa de caldera innecesaria y cosas por el estilo.

Idealmente, me gustaría aprender algoritmos en C, para que puedas saber qué está pasando a nivel de memoria; También me gustaría aprender algoritmos en un lenguaje funcional, para que pueda ver cómo funcionan algoritmos similares con estructuras de datos persistentes.

Los famosos libros de Knuth contienen grandes cantidades de código ensamblador (plataforma inventada). Esto se recomienda si quieres ser súper duro. Personalmente, sin embargo, trabajé en C cuando estaba trabajando en mi clase de algoritmos (revelación: esto fue hace solo un par de años). A veces trabajo en algunos problemas en Knuth, pero no sé si elegiría MMIX por completo como mi idioma de elección para aprender algoritmos. Creo que es un poco exagerado.

EDITAR : También depende de con lo que esté familiarizado. Si desea comenzar a trabajar a través de un texto de algoritmos en este momento, y nunca ha trabajado mucho con C, entonces Python es de lejos la respuesta correcta. Quieres que el idioma no sea un gran obstáculo que superar, porque quieres disfrutarlo. Sé que lo hice.

Último punto: al menos cuando estaba aprendiendo algoritmos, pasaba muchísimo tiempo trabajando en papel. Creo que eso es importante, quiero decir que quieres aprender sobre asintóticos, etc. Pasar todo tu tiempo implementando algoritmos en cualquier idioma no es lo que debes hacer.

Rob Lachlan
fuente
@Rob Lachlan: ¿Recomendarías algún libro de DS & A basado en Python?
bguiz
@bguiz: la mayoría de los libros decentes sobre algoritmos que me gustan son independientes del lenguaje: Cormen et al., Kleinberg y Tardos. Realmente no elegiría uno en función del idioma.
Rob Lachlan
8

Sugeriría a Ada. Tiene características para construcciones de datos que no se encuentran en otros lenguajes, como comprobaciones de rango. type Day is range 1 .. 31;También tiene comprobaciones muy estrictas en tiempo de compilación y ejecución (a menos que elija desactivarlo), lo que facilita la búsqueda de errores en su implementación.

Daniel Rose
fuente
8

Oberon-2 o Componente Pascal . El último es un superconjunto del primero.

Einstein dijo una vez: "Hágalo lo más simple posible, pero no más simple". Esta frase fue elegida por el profesor Niklaus Wirth como epígrafe del informe lingüístico original de Oberon. Y es cierto para los descendientes de Oberón mencionados anteriormente.

Cuando se trata de la perfección del lenguaje de programación, me gusta citar a Antoine de Saint-Exupéry: "Un diseñador sabe que ha llegado a la perfección no cuando ya no hay nada que agregar, sino cuando ya no hay nada que quitar". . Wirth, incluso si no lo logró, está en el camino correcto. En "Línea de lenguajes de programación Wirth" (Algol -> Pascal -> Modula-2 -> Oberon -> Oberon-2) cada lenguaje subsiguiente es más simple y al mismo tiempo más poderoso que el anterior.

Lenguajes potentes pero sencillos que siguen el principio de la mínima sorpresa. Tipado estático fuerte, facilidades orientadas a objetos fáciles, recolección de basura. La lista de funciones no es grande, pero es suficiente para ser productivo y no complicar las cosas, especialmente en las etapas iniciales.

Cuando quiere aprender algoritmos y estructuras de datos, lo dice en serio. Pero si su lenguaje es "poderoso" (tiene muchas características como C ++, C #, Java, Python, ...) perderá mucho tiempo aprendiendo lenguaje, no algoritmos ni estructuras de datos. No verás el bosque por los árboles. =) Puede pensar en los árboles como elementos de sintaxis (y cualquier otra característica) y en el bosque como un concepto importante (cualquier algoritmo, estructura de datos, puede ser POO, lo que sea). Cuantas más características (árboles) tenga en su idioma, más complicada será la tarea de dar un paso atrás y comprender los conceptos (ver el bosque).

Pero si el lenguaje es realmente poderoso (tiene un pequeño conjunto de características bien probadas), el lenguaje en sí pasa a un segundo lugar. No hay tantos árboles, así que puedes dar un par de pasos hacia atrás y ... Bueno, creo que son suficientes analogías. =)

Además, muchos libros sobre algoritmos y estructuras de datos utilizan pseudocódigo similar a Algol / Pascal y será fácil convertir ejemplos en estos lenguajes. Y puede utilizar directamente ejemplos del libro "Algoritmos y estructuras de datos" de Wirth. Edición de Oberon (2004), PDF (1,2 MB).

Algunos enlaces adicionales:

Gato montés
fuente
@kemiisto: gracias por la respuesta única y novedosa, ¡y las analogías! También investigaré Oberon-2.
bguiz
2
La versión en inglés del proverbio es "No puedo ver el bosque por los árboles".
Daniel Rose
6

"Si su única herramienta es un martillo, todos sus problemas tenderán a parecer clavos"

Aprenda al menos algunos idiomas.

Además, su elección depende de su propósito.

¿Pasatiempo? ¿Trabajo en el mundo de Windows? Familia Linux / UNIX?

Tipo de aplicaciones: empresarial versus científica; controladores de hardware o aplicaciones?

¿Aplicaciones de escritorio o aplicaciones web?

Tengo varias sugerencias para ti.

(a) definitivamente aprenda algo de J (gratis de jsoftware.com; sucesor de APL; tanto J como APL son creaciones de Ken Iverson, ganador de Turing ... El premio Turing es como el premio Nobel de informática).

(b) si está en el mundo de Windows, comience con c # porque gran parte de .NET se ejecuta en c #. Si puede, obtenga una copia de "Inside c #" de Tom Archer de Microsoft Press. Puede obtener un sistema de desarrollo c # gratuito descargando la versión expresa de Microsoft.

(c) aprender a usar TDD / BDD ... independientemente del idioma, primero escribe una pequeña prueba llamada prueba de unidad; a continuación, escribe el código de producción para pasar la prueba unitaria; un pequeño paso a la vez ... no es solo el lenguaje que utiliza, también es la metodología.

(d) aprender algo de lenguaje ensamblador ... ensamblador es de bajo nivel, casi lenguaje de máquina, le dará una buena comprensión de lo que está sucediendo detrás de escena.

(e) fuera del mundo de Windows, recomendaría c ++.

No existe el mejor idioma.

Si solo se tratara de lenguaje, la programación sería más fácil.

No solo desea aprender algoritmos que son muy específicos, sino que también desea aprender patrones que son más generales y pueden ayudarlo a seleccionar el enfoque para resolver un problema dado.

Una cosa es segura: es probable que nunca te quedes sin cosas que aprender si vas a convertirte en programador.

gerryLowry
fuente
Las estructuras de datos de @bguiz pueden ser, a todos los efectos, totalmente independientes del idioma; esta es una razón para aprender diferentes idiomas. También encontrará diferencias sutiles que pueden causar frustración e incluso dolor; ejemplo, nomenclatura del tipo de datos: bit para SQL Server es bool para c # y booleano para vb. el tamaño del tipo de datos también varía; ejemplo, int en c # se fija en 32 bits mientras que en c ++ su tamaño y por lo tanto su capacidad de almacenamiento depende de la plataforma. Los conjuntos de caracteres también afectan el tamaño de su estructura de datos; ejemplos, ASCII de 7 bits, ASCII de 8 bits, Unicode. Luego está el tamaño fijo frente a los variables, etcétera.
gerryLowry
"Las estructuras de datos pueden ser, a todos los efectos, totalmente independientes del lenguaje". Para implementar la mayoría de las estructuras de datos puramente funcionales en un lenguaje que no proporciona recolección de basura, básicamente tendrá que escribir un recolector de basura. Ese es un grave impedimento.
JD
Una vez que domine OO, intente cubrir la programación declarativa.
barba gris
4

Puede apreciar un lenguaje con tipos de datos algebraicos y coincidencia de patrones como Standard ML, OCaml, F # o Haskell. Por ejemplo, aquí hay una función para reequilibrar un árbol de búsqueda binario rojo-negro escrito en OCaml / F #:

let balance = function
  | R(R(a, x, b), y, c), z, d | R(a, x, R(b, y, c)), z, d
  | a, x, R(R(b, y, c), z, d) | a, x, R(b, y, R(c, z, d)) ->
      R(B(a, x, b), y, B(c, z, d))
  | a, x, b -> B(a, x, b)
JD
fuente
10
Se agradece su sarcasmo, señor.
ergosys
4

Creo que vale la pena investigar Lisp.

Mi primer curso de programación universitaria fue en Lisp. Antes de eso, había estado escribiendo programas en varios idiomas durante 10 años. Pensé que el primer curso de programación sería aburrido, pero me equivoqué.

Lisp es un lenguaje muy interesante porque tiene una sintaxis muy simple. El enfoque cambia de la sintaxis a la funcionalidad. El estilo de programación funcional también es algo muy valioso para aprender. Después de mi curso de Lisp, me encontré escribiendo programas en C ++ de una manera completamente nueva y mejor, gracias a los nuevos conceptos que Lisp me había enseñado.

Lisp también usa la misma representación para el código y los datos, lo que se abre a un interesante diseño de algoritmos con código generado sobre la marcha y luego ejecutado.

Anders Abel
fuente
2

Puede que me equivoque, pero ¿las estructuras de datos y los algoritmos no son independientes de los lenguajes de programación?

Al final, las estructuras de datos son solo una forma de organizar los datos; cualquier idioma de alto nivel lo apoyará. Por supuesto, ciertos lenguajes tendrán mecanismos que implementan estructuras de datos básicas (como Collections Framework en Java o C ++ STL), pero esto no le impide programar la estructura de datos en el lenguaje de programación que elija. Además, los algoritmos están escritos en pseudocódigo, lo que los hace independientes del lenguaje.

Me doy cuenta de que en realidad no responde a su pregunta, pero me cuesta entender lo que está buscando; aprender estructuras de datos / algoritmos o aprender un nuevo idioma.

Pran
fuente
1
@Pran: Sé que los algoritmos están en pseudocódigo, pero el pseudocódigo no se compilará. Soy un aprendiz de tipo práctico, por lo que para comprender realmente los conceptos, necesitaría codificarlo en un lenguaje que pueda compilar y ejecutar. Por lo tanto, mi pregunta realmente es cuál es el idioma más adecuado para esto, en el sentido de que cada idioma debería tener sus pros y sus contras, lo que hace que algunos de ellos sean más adecuados para aprender DS&A que otros.
bguiz
@Pran: "Puede que me equivoque, pero ¿las estructuras de datos y los algoritmos no son independientes de los lenguajes de programación?". Si el idioma no proporciona un GC, es posible que deba escribir uno.
JD
2

Cualquier lenguaje excepto el feo C ++ debería funcionar bien.

Jeremy José
fuente
0

Prefiero C ++ :)

Prasoon Saurav
fuente
19
-1 C ++ es un lenguaje de aprendizaje terrible (y podría decirse que puede eliminar el calificativo de "aprendizaje" de esa declaración).
cletus
4
No necesita aprender los rincones oscuros de C ++ para codificar sus algoritmos en C ++. C ++ está perfectamente bien.
Prasoon Saurav
9
por lo que cree que es una buena idea intentar codificar una clase para un DS en C ++ y ponerse al día con las diferencias entre un constructor de copia y anular el operador igual, las referencias y los punteros que se salen del alcance, pérdida de memoria debido a una nueva / eliminación incorrecta uso, etc? Todos los cuales son bastante fundamentales para C ++.
cletus
5
pero el punto es que no TIENES que aprender esas cosas en Python o Java. C ++ requiere una inversión inicial mucho mayor y de ninguna manera es más valioso para la función solicitada por el OP
Mantas Vidutis
2
¿Alguna razón válida para que Javascript no sea recomendable para aprender @cletus?
HalfWebDev