Khi nào cây nhị phân tốt hơn hashtables trong các ứng dụng trong thế giới thực?


7

Tôi hiện đang nghiên cứu cấu trúc dữ liệu và các thuật toán cơ bản của mình, một phần trong số đó là Cây nhị phân. Tôi hiểu các thuật toán và cách triển khai cây tìm kiếm nhị phân và như vậy. Tôi làm như vậy thông minh đến mức chúng ta có thể thực hiện tra cứu trong thời gian O (log n).

Tuy nhiên, tôi gặp khó khăn khi tìm một ví dụ về việc khi nào tôi sẽ sử dụng cây nhị phân, trong đó một bảng băm sẽ không làm công việc tương tự / tốt hơn. Tôi đã thực hiện một số tìm kiếm xung quanh và thấy rằng nó được sử dụng cho đồ thị 3D, một cái gì đó về những mục sẽ được hiển thị, tuy nhiên tôi có một thời gian khó khăn liên quan đến điều này.

Có ai có thể cho tôi một ví dụ về việc sử dụng cây nhị phân trên bảng băm sẽ tốt hơn không?

Câu trả lời:


14

Các bảng băm chỉ có thể cho bạn biết nếu một phần tử có mặt hay không.

Dưới đây là một số điều bạn có thể làm với cây nhị phân mà bạn không thể thực hiện với bảng băm.

  • sắp xếp ngang qua của cây
  • tìm phần tử gần nhất tiếp theo
  • tìm tất cả các yếu tố nhỏ hơn hoặc lớn hơn một giá trị nhất định

Xem bài viết wikipedia này về cây Kd để biết ví dụ về cấu trúc dữ liệu trong thế giới thực, sử dụng các thuộc tính đặc biệt của cây nhị phân. http://en.wikipedia.org/wiki/K-d_tree


1
Ngoài ra, có bảo đảm thời gian chạy tuyến tính phụ trường hợp xấu nhất.
Raphael

11

Một miền ứng dụng nơi cây nhị phân tốt hơn hoặc dễ điều chỉnh hơn các lựa chọn thay thế nhất định là các cấu trúc dữ liệu liên tục (thường được sử dụng trong lập trình chức năng (hoàn toàn)).

Cấu trúc dữ liệu liên tục là cấu trúc dữ liệu bảo tồn phiên bản trước của chính nó khi nó được sửa đổi. (Cấu trúc dữ liệu không có thuộc tính này được gọi là phù du .) Một lợi ích của loại cấu trúc dữ liệu này là cho phép chia sẻ các phần của cấu trúc dữ liệu - vì cấu trúc được đảm bảo không thay đổi, nên an toàn khi chia sẻ nó. tự do giữa các cấu trúc dữ liệu khác và thậm chí các luồng mà không lo nó thay đổi. Một lợi ích chủ quan khác là các cấu trúc dữ liệu này dễ dàng lý luận hơn.

Về mặt khái niệm, bạn có thể có một loại dữ liệu bất biến là danh sách các số, ví dụ: . Sau đó, bạn có thể giới thiệu một giá trị mới thêm hai số vào trước danh sách này: . Điều gì đã xảy ra với ? Không có gì - , vẫn vậy. Đã sao chép những ba yếu tố và đưa nó vào danh sách riêng của mình, sau đó? Lý tưởng nhất là không - các giá trị trong danh sách thuộc về :L1= ={3,4,5}L2= =conS(1,conS(2,L1))= ={1,2,3,4,5}L1L1= ={3,4,5}L2L1L2

1,2,3,4,5L1L2

Có các cấu trúc dữ liệu phù hợp hơn để thực hiện các danh sách liên tục như ở trên. Trong cùng một hướng, cây nhị phân rất phù hợp để thực hiện các cấu trúc dữ liệu liên tục với các thuộc tính nhất định, hơn các cấu trúc dữ liệu hoặc chiến lược khác. Và chia sẻ cấu trúc được hiển thị trong ví dụ với hai danh sách chuyển sang cây nhị phân - bạn có thể tưởng tượng rằng một số phiên bản của cây có thể chia sẻ các cây con mà chúng có chung.

Giống như tôi đã nói, một số cấu trúc dữ liệu dễ dàng sửa đổi hơn để tồn tại. Bạn đề cập đến bảng băm, thường là (nếu không nhất thiết) một cấu trúc dữ liệu phù du. Dường như ít rõ ràng hơn về cách người ta có thể điều chỉnh một chiến lược thực hiện chung để bảng băm được duy trì. Hãy xem xét rằng một bảng băm thường được triển khai với một mảng (cụ thể là các mảng được triển khai như một phần liên tục của bộ nhớ). Mảng rất hay vì chúng cung cấp quyền truy cập ngẫu nhiên vào các phần tử, đây là một thuộc tính quan trọng vì bạn lý tưởng muốn cóÔi(1)truy cập trung bình vào các yếu tố trong bảng băm. Nhưng mảng không đẹp khi xây dựng cấu trúc dữ liệu liên tục. Ý chính của nó là, trong khi bạn có thể tạo một kiểu dữ liệu mảng bất biến, theo bản chất của mảng, bạn có nguy cơ phải sao chép nhiều - Nếu loại Danh sách nói trên được triển khai bằng mảng, bạn sẽ có nguy cơ phải tạo một mảng toàn bộ mảng mới với năm yếu tố, thay vì chia sẻ một phần của nó. Và nếu bạn muốn sửa đổi một cái gì đó ở giữa mảng thì sao? Câu trả lời rõ ràng nhất - và dường như không thể tránh khỏi - là, một lần nữa, sao chép .

Cấu trúc dữ liệu liên tục không tránh việc phải sao chép, nói chung. Nhưng cấu trúc dữ liệu nhất định làm cho việc sao chép ít thường xuyên hơn. Đây là một tài sản mong muốn khi bạn yêu cầu một cấu trúc dữ liệu phải bất biến.


Các vấn đề với các mảng liên tục mà bạn đề cập trong đoạn thứ hai đến cuối cùng có lẽ là lý do tại sao Clojure thực hiện các vectơ truy cập ngẫu nhiên của nó với các cây lớn, phẳng thay vì sử dụng mảng Java. Họ cóÔi(đăng nhập32(n)) thời gian truy cập thay vì Ôi(1), nhưng họ có thể chia sẻ cấu trúc dễ dàng.
tsleyon

1
Tôi đã từng sử dụng các cây đỏ đen hoàn toàn có chức năng trong một chương trình Java để lưu trữ một số lượng lớn các bit tương tự, giúp giảm đáng kể việc sử dụng bộ nhớ và cho phép tôi nhanh chóng tính toán hệ số tương tự Jaccard của chúng. Những cây như vậy cũng có thể được so sánh một cách hiệu quả cho sự bình đẳng (trong) bằng cách duy trì hàm băm - ví dụ: bằng cách mỗi nút lưu trữ XOR băm của các nhánh của nó; Đây là chuyện nhỏ để duy trì dưới các vòng quay.
jkff

4

Cây nhị phân có nhiều ứng dụng, đặc biệt nếu chúng ta bao gồm tất cả các cây nhị phân chứ không chỉ cây tìm kiếm nhị phân. Heaps được triển khai dưới dạng cây nhị phân trong đó phần tử trên cùng là giá trị tối thiểu hoặc tối đa của tất cả các phần tử, rất hữu ích cho kịch bản yêu cầu hàng đợi ưu tiên.

Hashmap rất hiệu quả trong một loại hoạt động được thiết lập trong đó người ta chỉ cần kiểm tra sự tồn tại của một phần tử. Nhưng chúng yếu hơn khi thực hiện các hoạt động kiểm tra không tồn tại trên dữ liệu được sắp xếp hoặc sắp xếp. Hơn nữa, trong khi có thể điều chỉnh các thuật toán băm, cây nhị phân dường như hỗ trợ tốt hơn cho khái niệm tìm kiếm khóa một phần. Ví dụ, người ta có thể thử sử dụng một chuỗi các chuỗi nhị phân để trả lời những từ nào bắt đầu bằng "an". Cấp một bộ ba sẽ là một cấu trúc dữ liệu tốt hơn cho loại kịch bả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.