Làm thế nào để tôi chọn một cấu trúc dữ liệu từ điển chức năng?


10

Tôi đã đọc một chút về các cấu trúc dữ liệu sau:

  • Thử thách Hash lý tưởng của Bagwell
  • Bảng băm động của Larson
  • Cây đỏ-đen
  • Cây Patricia

... Và tôi chắc chắn có rất nhiều người khác ở ngoài đó. Tôi đã thấy rất ít theo cách mà mỗi người phù hợp hơn, hoặc tại sao tôi lại chọn cái này hơn cái khác. Vì vậy, đây là một vài câu hỏi dọc theo những dòng này:

  1. Những cấu trúc dữ liệu từ điển chức năng là quan trọng để biết về?
  2. Những ưu và nhược điểm của các phương pháp này là gì?
  3. Khi nào nó có ý nghĩa để sử dụng một cấu trúc dữ liệu cấp bách hơn?

Số 2 & 3 là những số quan trọng hơn mặc dù. :-)


Liên quan: Có gì mới trong cấu trúc dữ liệu chức năng thuần túy kể từ Okasaki? (Câu hỏi đó không giới hạn trong từ điển.)
Tsuyoshi Ito

Câu hỏi này (ngoài mục số 3) có cảm giác về một [danh sách lớn].
Kaveh

2
Sẽ rất hữu ích khi biết liệu câu hỏi được liên kết ở trên có giải quyết được mối quan tâm của bạn không, và nếu không thì tại sao không?
Suresh Venkat

@Suresh - Đó là câu trả lời số 1, nhưng 2 và 3 là những câu quan trọng hơn. Tôi chủ yếu tìm kiếm một cái nhìn tổng quan về bức tranh lớn để tôi có thể xác định cái nào đáng để nghiên cứu sâu hơn.
Jason

2
đồng ý. Vì vậy, nó có thể có giá trị chỉnh sửa câu hỏi sau đó.
Suresh Venkat

Câu trả lời:


16

Tôi thực sự không thể trả lời # 2 mà không bị lạc (có quá nhiều thứ mà bạn có thể so sánh các cấu trúc này), nhưng với # 3, câu trả lời khá đơn giản.

Sử dụng cấu trúc dữ liệu bắt buộc nếu: (a) hoàn toàn không có bí danh hoặc (b) bạn thực sự cần sử dụng bí danh để phát sóng hiệu quả.

Nếu không có bí danh nào về cấu trúc dữ liệu của bạn, thì bạn không lợi dụng thực tế là các cấu trúc dữ liệu chức năng vẫn tồn tại. Vì vậy, không có lý do để trả cho chi phí của họ. Có hai hãy cẩn thận với lời khuyên này. Trước tiên, bạn có thể thích sự đơn giản của việc thực hiện cấu trúc dữ liệu chức năng: thực hiện xóa đối với cây đỏ đen chức năng sẽ khiến bạn nguyền rủa, nhưng thực hiện xóa trong cây đen đỏ bắt buộc với con trỏ cha mẹ sẽ khiến bạn phải tự tử. Thứ hai, sự phân công có thể tốn kém hơn bạn mong đợi trong ngôn ngữ gc'd, vì việc ghi có thể khiến các cấu trúc dữ liệu bị loại bỏ khỏi thế hệ trẻ. Chúng tôi thực sự không có một lý thuyết tốt về hiệu ứng bộ đệm và gc, vì vậy bạn không có lựa chọn nào khác ngoài việc làm điểm chuẩn.

Thứ hai, nếu bạn cần một kênh phát sóng, thì cấu trúc dữ liệu được chia sẻ là một cách tuyệt vời để làm điều đó. Với cập nhật liên tục, bạn có thể tùy ý nói với nhiều người khác rằng giá trị đã thay đổi. (Đây là lý do tại sao union-find là một cấu trúc dữ liệu tuyệt vời như vậy.) Với thiết lập chức năng thuần túy, bạn cần phải sửa đổi tất cả những người khác hoặc cung cấp cho họ các con trỏ trừu tượng vào trạng thái bạn mã hóa thủ công (đây là một loại khó hiểu việc cần làm).

Nếu bạn không muốn lý do về bí danh và quyền sở hữu đối tượng hoặc nếu bạn cần nhiều phiên bản của cùng một cấu trúc dữ liệu (bạn cần cả phiên bản mới và phiên bản cũ, thì chỉ cần sử dụng cấu trúc dữ liệu chức năng.

Nơi tôi tìm thấy theo lời khuyên này khó nhất là với các thuật toán đồ thị. Có rất nhiều thuật toán đồ thị mệnh lệnh thực sự thanh lịch, nhưng thường thì (giả sử, khi viết trình biên dịch) mà bạn cũng muốn kiên trì. Mọi người thường cố gắng phân chia sự khác biệt và sử dụng thuật toán mệnh lệnh tuyệt vời nhưng cố gắng đẩy phiên bản sang một bên để có được sự kiên trì. Điều này nói chung là khá khủng khiếp, đầy lỗi và dễ bị mất lợi thế về hiệu suất của thuật toán bắt buộc.


2
răng cưa trong bối cảnh này là gì?
Suresh Venkat

6
Bí danh là khi bạn có nhiều tham chiếu đến cùng một dữ liệu. Nếu dữ liệu đó có thể thay đổi, thì lý do về một chương trình sử dụng nó phải xem xét rõ ràng tất cả các chương trình con khác có thể truy cập và sửa đổi nó. Nếu phần dữ liệu đó là bất biến, thì bạn có thể suy luận cục bộ về một chương trình sử dụng nó, bỏ qua bí danh, vì bạn biết không ai có thể truy cập dữ liệu có thể sửa đổi nó.
Neel Krishnaswami

"nhưng thực hiện xóa trong một cây đen đỏ bắt buộc với con trỏ cha mẹ sẽ khiến bạn phải tự tử" Hãy xem những cây đen đỏ nghiêng trái của Sedgewick. Trường hợp xóa chung được giảm xuống thành xóa-min bằng một thủ thuật tiêu chuẩn và chính việc xóa-min rất đơn giản đối với các cây LLRB. Không có con trỏ cha mẹ cần thiết.
Per Vognsen

1
"Điều này nói chung là khá khủng khiếp, đầy lỗi và dễ bị mất lợi thế về hiệu suất của thuật toán bắt buộc." Bài viết của Norman Ramsey về việc sử dụng khóa kéo cho biểu đồ luồng điều khiển trong trình biên dịch tối ưu hóa cung cấp một ví dụ về sự thỏa hiệp hấp dẫn. Bạn thực sự có một đống cục bộ để hỗ trợ việc nối lại các tham chiếu giữa các khối cơ bản trong CFG một cách dễ dàng và hiệu quả, nhưng thao tác nội dung của các khối cơ bản là chức năng (hoặc bán chức năng, tùy thuộc vào quan điểm triết học của bạn về dây kéo).
Per Vognsen

1

Những cấu trúc dữ liệu từ điển chức năng là quan trọng để biết về?

Cây nhị phân cân bằng chiều cao và cố gắng của chúng là một sự thỏa hiệp toàn diện tốt. Cũng thế:

  • Cây Patricia.
  • Hash cố gắng.

Những ưu và nhược điểm của các phương pháp này là gì?

Cây nhị phân cân bằng chiều cao và cố gắng của chúng là một sự thỏa hiệp toàn diện tốt cho các khóa nguyên tử. Các thử nghiệm giống nhau đối với các khóa là chuỗi, ví dụ: khóa chuỗi.

Cây Patricia có thể nhanh hơn nhiều lần nhưng chỉ cho phép các khóa số nguyên.

Các lần băm có thể nhanh hơn nhiều lần so với cây nhị phân cân bằng, đặc biệt nếu băm rẻ hơn so với so sánh và đa hình có chi phí hoạt động (ví dụ: chuỗi trên .NET) và ghi con trỏ vào heap rất nhanh (ví dụ: VM như JVM và CLR đã được tối ưu hóa cho các ngôn ngữ bắt buộc hơn là ngôn ngữ chức năng). Hash cố gắng cũng cho phép sử dụng nội bộ của đột biến như một tối ưu hóa.

Cây đỏ đen ít quan trọng hơn vì chúng không có bất kỳ lợi ích đáng kể nào so với cây cân bằng chiều cao nhưng có nhược điểm đáng kể là chúng không cho phép kết hợp, giao nhau và khác biệt hiệu quả.

Tương tự, cây ngón tay không tốt hơn nhiều trong thực tế.

Khi nào nó có ý nghĩa để sử dụng một cấu trúc dữ liệu cấp bách hơn?

Khi từ điển của bạn được điền một lần và sau đó chỉ được sử dụng để tra cứu, tức là bị đóng băng.

Khi bạn cần hiệu năng (một bảng băm tốt như .NET Dictionarythường nhanh hơn 10-40 × so với bất kỳ từ điển chức năng thuần túy chung nào).

Khi bạn cần một từ điển yếu vì không có từ điển yếu hoàn toàn chức năng được biết đến.

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.