Câu trả lời cho câu hỏi này phụ thuộc vào chính xác những gì bạn muốn học.
Python và Ruby
Các ngôn ngữ cấp cao như Python và Ruby thường được đề xuất vì chúng ở cấp cao và cú pháp khá dễ đọc. Tuy nhiên, tất cả các ngôn ngữ này đều có tính trừu tượng đối với các cấu trúc dữ liệu chung. Không có gì ngăn cản bạn triển khai các phiên bản của riêng mình như một bài tập học tập nhưng bạn có thể thấy rằng bạn đang xây dựng cấu trúc dữ liệu cấp cao trên các cấu trúc dữ liệu cấp cao khác, điều này không nhất thiết hữu ích.
Ngoài ra, Ruby và Python là các ngôn ngữ được nhập động. Điều này có thể tốt nhưng nó cũng có thể gây nhầm lẫn cho người mới bắt đầu và có thể khó bắt lỗi hơn (ban đầu) vì chúng thường sẽ không rõ ràng cho đến khi chạy.
C
C ở cực còn lại. Thật tốt nếu bạn muốn tìm hiểu các chi tiết thực sự ở mức thấp như cách quản lý bộ nhớ nhưng quản lý bộ nhớ đột nhiên là một yếu tố quan trọng cần cân nhắc, chẳng hạn như cách sử dụng đúng malloc () / free (). Điều đó có thể gây mất tập trung. Ngoài ra, C không phải là hướng đối tượng. Đó không phải là một điều xấu mà chỉ đơn giản là đáng lưu ý.
C ++
C ++ đã được đề cập. Như tôi đã nói trong phần bình luận, tôi nghĩ đây là một sự lựa chọn khủng khiếp . C ++ cực kỳ phức tạp ngay cả khi sử dụng đơn giản và có rất nhiều "gotchas" vô lý. Ngoài ra, C ++ không có lớp cơ sở chung. Điều này rất quan trọng vì cấu trúc dữ liệu như bảng băm dựa vào đó là một lớp cơ sở chung. Bạn có thể triển khai một phiên bản cho lớp cơ sở danh nghĩa nhưng nó kém hữu ích hơn một chút.
Java
Java cũng đã được đề cập. Nhiều người thích ghét Java và đúng là ngôn ngữ này cực kỳ dài dòng và thiếu một số tính năng ngôn ngữ hiện đại hơn (ví dụ: bao đóng) nhưng không có gì thực sự quan trọng. Java được gõ tĩnh và có tính năng thu gom rác. Điều này có nghĩa là trình biên dịch Java sẽ bắt được nhiều lỗi mà các ngôn ngữ được nhập động sẽ không xảy ra (cho đến thời gian chạy) và không xử lý được lỗi phân đoạn (không có nghĩa là bạn không thể rò rỉ bộ nhớ trong Java; rõ ràng là bạn có thể). Tôi nghĩ Java là một lựa chọn tốt.
C #
C # là ngôn ngữ giống như một phiên bản Java hiện đại hơn. Giống như Java, nó là một ngôn ngữ biên dịch trung gian được quản lý (thu gom rác) chạy trên một máy ảo. Mọi ngôn ngữ khác được liệt kê ở đây ngoài C / C ++ cũng chạy trên một máy ảo nhưng Python, Ruby, v.v. được thông dịch trực tiếp thay vì biên dịch sang mã bytecode.
Về cơ bản, C # có những ưu và nhược điểm giống như Java.
Haskell (v.v.)
Cuối cùng, bạn có các ngôn ngữ chức năng: Haskell, OCaml, Scheme / Lisp, Clojure, F #, v.v. Những ngôn ngữ này suy nghĩ về tất cả các vấn đề theo một cách rất khác và đáng để học tại một số điểm nhưng nó lại đi vào những gì bạn muốn học: lập trình chức năng hoặc cấu trúc dữ liệu? Tôi muốn học từng thứ một thay vì nhầm lẫn vấn đề. Nếu bạn học một ngôn ngữ chức năng tại một số điểm (mà tôi muốn giới thiệu), Haskell là một lựa chọn an toàn và tốt.
Lời khuyên của tôi
Chọn Java hoặc C #. Cả hai đều có IDE miễn phí, tuyệt vời (Eclipse, Netbeans và IntelliJ Community Edition cho Java, Visual Studio Express cho C #, phiên bản cộng đồng Visual studio) giúp việc viết và chạy mã trở nên nhanh chóng. Nếu bạn không sử dụng cấu trúc dữ liệu gốc nào phức tạp hơn một mảng và bất kỳ đối tượng nào bạn tự viết, bạn sẽ học về cơ bản giống như bạn học trong C / C ++ nhưng không cần thực sự quản lý bộ nhớ.
Hãy để tôi giải thích: một bảng băm có thể mở rộng cần được thay đổi kích thước nếu đã thêm đủ phần tử. Trong bất kỳ triển khai nào có nghĩa là thực hiện một số việc như tăng gấp đôi kích thước của cấu trúc dữ liệu hỗ trợ (thường là một mảng) và sao chép trong các phần tử hiện có. Việc triển khai về cơ bản là giống nhau trong tất cả các ngôn ngữ mệnh lệnh nhưng trong C / C ++, bạn phải đối mặt với các lỗi phân đoạn khi bạn không phân bổ hoặc phân bổ thứ gì đó một cách chính xác.
Python hoặc Ruby (nó không thực sự quan trọng) sẽ là lựa chọn tiếp theo của tôi (và rất gần với hai cái kia) chỉ vì lúc đầu, việc nhập động có thể có vấn đề.