Mối quan hệ giữa cấu trúc dữ liệu và thuật toán là gì? [đóng cửa]


13

Tôi đã tìm kiếm một khóa học trực tuyến tốt về cấu trúc dữ liệu nhưng nhận thấy rằng Google cũng trả về kết quả cho các khóa học thuật toán, có nội dung như:

Trong khóa học này, bạn sẽ học một số nguyên tắc cơ bản của thiết kế thuật toán: phương pháp phân chia và chinh phục, thuật toán đồ thị, cấu trúc dữ liệu thực tế (heaps, bảng băm, cây tìm kiếm) , thuật toán ngẫu nhiên, v.v. [nguồn]

Đến cuối lớp này, bạn sẽ hiểu các khái niệm chính cần thiết để đưa ra các thuật toán mới cho đồ thị và các cấu trúc dữ liệu quan trọng khác và để đánh giá hiệu quả của các thuật toán này. [nguồn]

Khóa học này cung cấp một giới thiệu về mô hình toán học của các vấn đề tính toán. Nó bao gồm các thuật toán phổ biến, mô hình thuật toán và cấu trúc dữ liệu được sử dụng để giải quyết các vấn đề này . [nguồn]

Câu hỏi của tôi là: các thuật toán và cấu trúc dữ liệu được liên kết mật thiết với nhau, có nghĩa là chúng phải được hiểu cùng nhau hoặc là một chủ đề có tính nền tảng hơn các chủ đề khác?

EDIT: Đối với những người bỏ phiếu để đóng câu hỏi này, bạn có thể vui lòng cho tôi biết lý do và có thể làm thế nào để cải thiện câu hỏi này không? Học cách đặt câu hỏi đúng là một phần của quá trình giáo dục.


17
Một cấu trúc dữ liệu là tĩnh và không thể làm gì. Một thuật toán chỉ là một tập hợp các hướng dẫn để thực hiện trên một số dữ liệu. Không có cái này thì cái kia là vô dụng. Họ cùng nhau làm chương trình máy tính. Cả hai đều cơ bản.
Phoshi

2
@Phoshi Sai. Cấu trúc dữ liệu được liên kết chặt chẽ với các thuật toán thao túng dữ liệu. Vì vậy, gắn chặt các thuật toán được coi là một phần của cấu trúc dữ liệu. Ví dụ Cấu trúc dữ liệu Lined List cho bạn biết cách lưu dữ liệu và cũng như cách dữ liệu được đọc và thao tác.
Euphoric

7
@Euphoric Tôi cho rằng thật sai lầm khi nói rằng thuật toán là một phần của cấu trúc dữ liệu. Có nhiều hơn một cách để thực hiện tìm kiếm nhị phân: ví dụ, bạn có thể thực hiện if less than recurse to the left; if greater than, recurse to the right; if equal, returntìm kiếm ngây thơ hoặc tinh vi hơn một chút if less than recurse to the left; otherwise keep track of this value as a potential candidate and recurse to the right; check for equality once we reach the leaves. Họ có số lượng so sánh hơi khác nhau. Cả hai đều là một trong nhiều điều bạn có thể chọn để làm với một cái cây.
Doval

4
@Euphoric Bạn đang nhầm lẫn cấu trúc dữ liệu với kiểu dữ liệu trừu tượng mà sự kết hợp giữa cấu trúc dữ liệu và thuật toán thực hiện.
Doval

7
@Euphoric, tôi phải không đồng ý. hợp nhất sắp xếp là một thuật toán. Một mảng là một cấu trúc dữ liệu. Một danh sách liên kết là một cấu trúc dữ liệu khác nhau. Tôi có thể viết một triển khai MergeSort để hoạt động. Một số cấu trúc dữ liệu có thể tự nhiên hơn hoặc hiệu quả hơn đối với một thuật toán cụ thể, nhưng hiếm khi nó là một yêu cầu tuyệt đối (bạn thực sự phải có một đống để thực hiện sắp xếp heap). Nicholas Wirth đã viết một cuốn sách văn bản phổ biến vào những năm 1980 với tiêu đề: "Thuật toán + Cấu trúc dữ liệu = Chương trình"
Charles E. Grant

Câu trả lời:


20

Tất cả các loại hỗn hợp tồn tại. Bạn có cấu trúc dữ liệu, không liên quan đến thuật toán, thuật toán, không yêu cầu cấu trúc dữ liệu (thực), nhưng hầu hết cả hai đều có trong một gói.

Chỉnh sửa: như @Doval đã chỉ ra một cách chính xác, các cấu trúc dữ liệu trên mỗi se không có bất kỳ hoạt động nào liên quan đến chúng. Hành động kết hợp cấu trúc dữ liệu và thuật toán tạo thành một kiểu dữ liệu trừu tượng.

Cấu trúc dữ liệu không có thuật toán

Ví dụ, xem xét một cấu trúc dữ liệu để lưu trữ tọa độ 2 chiều, được gọi một cách thích hợp Point. Không có gì nhiều về các thuật toán được thực hiện cho một điểm và nó thực sự chỉ là một thùng chứa cho một giá trị xy. Tất nhiên, đưa ra cấu trúc dữ liệu này, giờ đây bạn có thể thêm tất cả các loại thuật toán lên trên nó (tính toán khoảng cách, vỏ lồi, những gì bạn có).

Bạn có thể nghĩ về rất nhiều cấu trúc dữ liệu, đơn giản chỉ là sự tích lũy dữ liệu riêng lẻ. Mặc dù những điều này xảy ra thường xuyên trong thực tế, nhưng chúng không tạo ra tài liệu giảng dạy tốt, bởi vì không có gì để học từ nó, một khi bạn đã hiểu, các mục dữ liệu đơn lẻ có thể được tích lũy vào cấu trúc dữ liệu mới (như bạn học được gì sau Pointví dụ trên , nếu tôi cung cấp cho bạn cấu trúc dữ liệu tuyệt vời đó được gọi Point3D, có thể làm điều tương tự cho không gian 3 chiều không?)

Các thuật toán không có cấu trúc dữ liệu (thực)

"Thực", vì rõ ràng mọi thuật toán thú vị đều cần các kiểu dữ liệu nguyên thủy như số nguyên hoặc booleans và chúng tôi không muốn coi chúng là cấu trúc dữ liệu trong ngữ cảnh này. Tương tự như trên, các thuật toán này thường khá đơn giản. Cụ thể, chúng không đi kèm với một trạng thái phức tạp nào, bởi vì điều đó thường đi vào cấu trúc dữ liệu (xem phần tiếp theo).

Một ví dụ cho thuật toán như vậy sẽ tính toán ước số chung lớn nhất của hai số. Các thuật toán của Euklid cho gcd thực sự chỉ cần giữ hai số nguyên và thao tác với chúng.

Khi mọi thứ bắt đầu trở nên thú vị hơn, bạn sẽ sớm bước vào thế giới của các loại dữ liệu trừu tượng. Ví dụ, sàng của Eratosthenes dựa trên một mảng. Bây giờ chúng ta có thể có một cuộc thảo luận, cho dù một mảng vẫn còn nguyên thủy hay thực tế, bạn có thể thảo luận nếu một số nguyên chưa phải là cấu trúc dữ liệu. Dù bằng cách nào, các thuật toán tồn tại hoàn toàn không có cấu trúc dữ liệu khá nhàm chán, ngay cả khi bạn chấp nhận sự tồn tại biệt lập của chúng.

Các thuật toán kết hợp với cấu trúc dữ liệu, còn gọi là các loại dữ liệu trừu tượng

Bây giờ đây là những người thú vị, nhưng vì hai lý do rất khác nhau. Thông thường, bạn có thể tiếp cận những điều này từ hai hướng: cấu trúc dữ liệu trước hoặc thuật toán trước.

Mặc dù kiểu dữ liệu trừu tượng được xác định bởi sự kết hợp của cấu trúc dữ liệu + thuật toán / thao tác, chúng tôi thường xem chúng tập trung vào một trong hai loại đó và coi cái kia là một yếu tố hỗ trợ.

Cấu trúc dữ liệu, sau đó là thuật toán

Bạn sẽ gặp các kiểu dữ liệu trừu tượng, khá đơn giản để sử dụng, nhưng liên quan đến các thuật toán phức tạp hơn hoặc ít hơn để làm cho chúng hoạt động bên trong. Ví dụ, a HashMaplà tầm thường để sử dụng, nhưng liên quan đến hàm băm tiện lợi và xử lý các va chạm băm ở bên trong. Tuy nhiên, từ quan điểm của bạn với tư cách là một người dùng, bạn quan tâm đến nó như một thứ giữ dữ liệu cho bạn, không phải là thứ gì đó làm cho bạn.

Trái ngược với nhóm cuối cùng bên dưới, các cấu trúc dữ liệu này không đưa người dùng của họ đến các thuật toán này. Bạn không cần biết, cũng không cần quan tâm đến HashMapchức năng băm nội bộ của s để có thể sử dụng nó. (Để sử dụng nó một cách hiệu quả, bạn có thể muốn biết những điều này;)

Thuật toán, sau đó cấu trúc dữ liệu

Hướng khác có nghĩa là bạn có một thuật toán mà bạn muốn có thể sử dụng đơn giản, nhưng cần cấu trúc dữ liệu bên trong để làm cho nó hoạt động như dự định. Một ví dụ sẽ là thuật toán phân vùng không gian nhị phân (BSP), bạn chỉ cần yêu cầu 2 chiều Pointtừ một tập hợp lớn các điểm gần nhất với một điểm truy vấn nhất định. Tuy nhiên, bạn cần một cấu trúc cây (và thậm chí các thuật toán bổ sung như tính toán khoảng cách) ở bên trong để thực sự viết thuật toán.

Nói chung, người ta có thể nói rằng các thuật toán trong nhóm này sử dụng các cấu trúc dữ liệu liên quan để biểu diễn trạng thái bên trong của chúng. Tôi sẽ lập luận rằng nhóm thuật toán này là đa dạng nhất và bạn sẽ tìm thấy nhiều thuật toán khác nhau phù hợp với sơ đồ chung này. Về quan điểm, chúng tôi thấy những điều này là thú vị, bởi vì họ làm điều gì đó (ví dụ như sắp xếp) cho chúng tôi và không quan tâm nhiều đến phần giữ dữ liệu.

Các cấu trúc dữ liệu và thuật toán liên quan chặt chẽ

Cuối cùng, bạn có các cấu trúc dữ liệu, rất liên quan đến các thuật toán tương ứng trực tiếp với chúng. Một ví dụ điển hình là cây nhị phân, khi bạn muốn làm bất cứ điều gì có ý nghĩa với nó, buộc chủ đề về thuật toán đi trên cây (trước hết, sâu trước, bất cứ điều gì).

Đối với những trường hợp này, chúng tôi thay đổi trọng tâm của quan điểm của chúng tôi về các loại dữ liệu trừu tượng kết quả thường xuyên. Đôi khi bạn quan tâm đến cấu trúc của cây, vài phút sau bạn quan tâm đến việc có thể chạy một hoạt động tìm kiếm trên nó, sau đó bạn tự hỏi về việc xóa một nút và ngay lập tức về cách cấu trúc trông sau đó. Mặc dù tất cả những điều này cũng đúng với các phần khác ở trên, nhưng nó không phải là trọng tâm chính trong tâm trí của bạn, ví dụ, khi bạn lưu trữ / truy xuất dữ liệu đến / từ một Maphoặc khi bạn sắp xếp danh sách được liên kết.


1
Bạn đang kết hợp cấu trúc dữ liệu và các loại dữ liệu trừu tượng. Một cấu trúc dữ liệu không làm gì cả . Thật vô nghĩa khi nói "bạn sẽ gặp các cấu trúc dữ liệu, khá đơn giản để sử dụng" bởi vì cấu trúc dữ liệu chỉ là một cấu trúc. A Maplà một kiểu dữ liệu trừu tượng có thể được thực hiện bằng cách sử dụng một cấu trúc dữ liệu cụ thể và một tập hợp các thuật toán tạo ra kết quả mong muốn bằng cách duyệt và thao tác cấu trúc. Cấu trúc dữ liệu không ẩn các thuật toán, vì nó không có thuật toán; kiểu dữ liệu trừu tượng che giấu cấu trúc dữ liệu (đó là điều làm cho nó trừu tượng.)
Doval

Lưu ý rằng theo một nghĩa nào đó, các thuật toán luôn bị ẩn bởi vì không có cách nào để kiểm tra các hàm. Đó có lẽ là lý do tại sao chúng được gọi là trừu tượng trong phép tính lambda (chỉ có kiểu dữ liệu là hàm).
Doval

2
Bạn nói đúng. Tuy nhiên, tôi thấy một sự khác biệt giữa cách chúng ta xem các ADT khác nhau. Tôi đã chỉnh sửa câu trả lời của mình và hy vọng nó đã rõ ràng hơn và không còn kết cấu cấu trúc với ADT, trong khi vẫn nhấn mạnh, rằng bạn có thể tập trung vào cấu trúc và / hoặc hoạt động cho bất kỳ ADT nào.
Frank

Có thực sự quá đơn giản để nói rằng cấu trúc dữ liệu là danh từ và thuật toán là động từ? Tôi cho rằng bạn có thể nói rằng thuật toán là việc thực hiện động từ, nhưng bạn vẫn tìm kiếm một cây , ngay cả khi tìm kiếm đó là tìm kiếm nhị phân. Bạn sẽ bỏ lỡ tất cả các chi tiết kỹ thuật bằng cách nói như vậy, nhưng nó có một sự thanh lịch nhất định.
Magus

@Doval: Ngay cả khi cấu trúc dữ liệu chỉ bao gồm một bó các số trong một mảng được yêu cầu phải có và duy trì mối quan hệ với nhau, thì điều đó có thể "dễ sử dụng" nếu dễ duy trì các bất biến cần thiết trong khi làm những gì người ta muốn, hoặc "khó sử dụng" nếu khó khăn.
supercat

5

Cấu trúc dữ liệu thường ảnh hưởng đến các chi tiết của một thuật toán. Vì điều này hai người thường đi đôi với nhau.

Ví dụ, xem xét một thuật toán để cắt cỏ của bạn. Làm thế nào bạn đi về việc cắt cỏ của bạn có thể bị ảnh hưởng bởi cấu trúc thực tế của bãi cỏ của bạn. Nếu bạn sống trong một ngôi nhà nhỏ ở vùng ngoại ô đông đúc và bãi cỏ của bạn chỉ là một hình chữ nhật nhỏ có diện tích vài mét vuông, bạn có thể thích cắt cỏ bằng máy cắt đẩy thay vì máy kéo / máy cắt cỏ. Nếu bãi cỏ của bạn liên quan đến nhiều mẫu đất bằng phẳng, sở thích của bạn có thể là máy cắt cỏ trái ngược với máy cắt đẩy (mặc dù cuối cùng máy cắt cỏ có thể hoàn thành công việc). Nếu bãi cỏ của bạn bao gồm một mẫu đất có diện tích bằng phẳng lớn, nhưng một vài ngọn đồi nhỏ và một số cây, bạn có thể phát triển một thuật toán thú vị hơn để cắt cỏ bao gồm cả máy cắt cỏ và máy cắt cỏ, hoặc một số loại cỏ khác kỹ thuật cắt.

Cuối cùng, cấu trúc dữ liệu của bạn có thể có tác động đáng kể đến các quyết định của bạn về cách phát triển thuật toán của bạn (hoặc sử dụng thuật toán nào). Vì lý do này, hai chủ đề thường đi đôi với nhau.

Và ngược lại: đôi khi thuật toán chúng tôi muốn sử dụng các ảnh hưởng (ít nhất là khi bắt đầu tính toán) các cấu trúc dữ liệu bạn phát triển để hỗ trợ thuật toán. Ví dụ: đi từ một danh sách mảng đến ý tưởng của một danh sách được liên kết và cuối cùng đến một BST để lưu trữ một danh sách theo thứ tự sẽ cho phép tìm nhanh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.