Dường như ở mọi nơi tôi nhìn thấy, các cấu trúc dữ liệu đang được triển khai bằng cách sử dụng các cây đỏ đen ( std::set
trong C ++, SortedDictionary
trong C #, v.v.)
Vừa mới bao phủ (a, b), cây đỏ-đen & AVL trong lớp thuật toán của tôi, đây là những gì tôi nhận được (cũng từ việc hỏi các giáo sư, xem qua một vài cuốn sách và googling một chút):
- Cây AVL có độ sâu trung bình nhỏ hơn cây đỏ đen và do đó tìm kiếm giá trị trong cây AVL luôn nhanh hơn.
- Cây đỏ đen tạo ra ít thay đổi cấu trúc hơn để tự cân bằng so với cây AVL, điều này có thể khiến chúng có khả năng chèn / xóa nhanh hơn. Tôi đang nói có khả năng, bởi vì điều này phụ thuộc vào chi phí thay đổi cấu trúc của cây, vì điều này sẽ phụ thuộc rất nhiều vào thời gian chạy và hàm ý (cũng có thể hoàn toàn khác nhau trong ngôn ngữ chức năng khi cây bất biến?)
Có rất nhiều điểm chuẩn trực tuyến so sánh cây AVL và cây Đen-đen, nhưng điều khiến tôi ngạc nhiên là về cơ bản, giáo sư của tôi đã nói rằng, thông thường bạn sẽ làm một trong hai điều sau:
- Hoặc bạn không thực sự quan tâm nhiều đến hiệu suất, trong trường hợp đó, chênh lệch 10-20% của AVL so với Đỏ-đen trong hầu hết các trường hợp sẽ không thành vấn đề.
- Hoặc bạn thực sự quan tâm đến hiệu suất, trong trường hợp bạn bỏ cả cây AVL và cây đỏ đen và đi với cây B, có thể được điều chỉnh để hoạt động tốt hơn nhiều (hoặc (a, b) -trees, tôi ' m sẽ đặt tất cả những thứ đó vào một giỏ.)
Lý do là bởi vì cây B lưu trữ dữ liệu gọn hơn trong bộ nhớ (một nút chứa nhiều giá trị) sẽ có ít lỗi nhớ cache hơn. Bạn cũng có thể điều chỉnh việc triển khai dựa trên trường hợp sử dụng và làm cho thứ tự của cây B phụ thuộc vào kích thước bộ đệm của CPU, v.v.
Vấn đề là tôi không thể tìm thấy hầu hết mọi nguồn phân tích việc sử dụng thực tế các cách thực hiện khác nhau của các cây tìm kiếm trên phần cứng hiện đại thực sự. Tôi đã xem qua nhiều cuốn sách về thuật toán và không tìm thấy bất cứ thứ gì có thể so sánh các biến thể cây khác nhau với nhau, ngoài việc chỉ ra rằng một cái có độ sâu trung bình nhỏ hơn cái kia (điều đó không thực sự nói nhiều về cách cây sẽ hành xử trong các chương trình thực tế.)
Điều đó đang được nói, có một lý do đặc biệt tại sao cây đen đỏ đang được sử dụng ở mọi nơi, khi dựa trên những gì được nói ở trên, cây B nên vượt trội hơn chúng? (như điểm chuẩn duy nhất tôi có thể tìm thấy cũng hiển thị http://lh3lh3.users.sourceforge.net/udb.shtml , nhưng nó có thể chỉ là vấn đề của việc triển khai cụ thể). Hay là lý do tại sao tất cả mọi người sử dụng cây Đỏ-đen vì chúng khá dễ thực hiện hoặc để đặt nó bằng các từ khác nhau, khó thực hiện kém?
Ngoài ra, điều này thay đổi như thế nào khi một người chuyển sang vương quốc của các ngôn ngữ chức năng? Có vẻ như cả Clojure và Scala đều sử dụng các thử nghiệm ánh xạ mảng Hash , trong đó Clojure sử dụng hệ số phân nhánh là 32.