Ưu điểm của cây tìm kiếm nhị phân so với bảng băm là gì?
Bảng băm có thể tra cứu bất kỳ phần tử nào trong thời gian Theta (1) và việc thêm một phần tử cũng dễ dàng như vậy .... nhưng tôi không chắc về những lợi thế theo chiều ngược lại.
Ưu điểm của cây tìm kiếm nhị phân so với bảng băm là gì?
Bảng băm có thể tra cứu bất kỳ phần tử nào trong thời gian Theta (1) và việc thêm một phần tử cũng dễ dàng như vậy .... nhưng tôi không chắc về những lợi thế theo chiều ngược lại.
Câu trả lời:
Hãy nhớ rằng Cây tìm kiếm nhị phân (dựa trên tham chiếu) tiết kiệm bộ nhớ. Họ không dự trữ nhiều bộ nhớ hơn mức họ cần.
Ví dụ: nếu một hàm băm có một phạm vi R(h) = 0...100
, thì bạn cần phải phân bổ một mảng gồm 100 phần tử (con trỏ đến), ngay cả khi bạn chỉ băm 20 phần tử. Nếu bạn sử dụng cây tìm kiếm nhị phân để lưu trữ cùng một thông tin, bạn sẽ chỉ phân bổ lượng không gian cần thiết cũng như một số siêu dữ liệu về các liên kết.
Một ưu điểm mà không ai khác đã chỉ ra là cây tìm kiếm nhị phân cho phép bạn thực hiện tìm kiếm phạm vi một cách hiệu quả.
Để minh họa cho ý tưởng của mình, tôi muốn đưa ra một trường hợp cực đoan. Giả sử bạn muốn lấy tất cả các phần tử có khóa từ 0 đến 5000. Và thực tế chỉ có một phần tử như vậy và 10000 phần tử khác có khóa không nằm trong phạm vi. BST có thể thực hiện tìm kiếm phạm vi khá hiệu quả vì nó không tìm kiếm một cây con không thể có câu trả lời.
Trong khi đó, làm cách nào bạn có thể thực hiện tìm kiếm phạm vi trong bảng băm? Bạn cần phải lặp lại mọi không gian nhóm, là O (n), hoặc bạn phải tìm xem mỗi trong số 1,2,3,4 ... lên đến 5000 có tồn tại hay không. (còn các khóa từ 0 đến 5000 là một tập hợp vô hạn thì sao? ví dụ các khóa có thể là số thập phân)
Một "lợi thế" của cây nhị phân là nó có thể được duyệt để liệt kê tất cả các phần tử theo thứ tự. Điều này không phải là không thể với bảng Hash nhưng không phải là một hoạt động bình thường khi thiết kế thành một cấu trúc băm.
Ngoài tất cả các bình luận hay khác:
Các bảng băm nói chung có hành vi bộ nhớ cache tốt hơn yêu cầu ít lần đọc bộ nhớ hơn so với một cây nhị phân. Đối với bảng băm, bạn thường chỉ phải đọc một lần đọc trước khi bạn có quyền truy cập vào một tham chiếu chứa dữ liệu của bạn. Cây nhị phân, nếu nó là một biến thể cân bằng, yêu cầu một thứ gì đó theo thứ tự của bộ nhớ k * lg (n) đọc cho một số hằng số k.
Mặt khác, nếu kẻ thù biết hàm băm của bạn, kẻ thù có thể ép buộc bảng băm của bạn để tạo ra các va chạm, cản trở hiệu suất của nó rất nhiều. Cách giải quyết là chọn hàm băm ngẫu nhiên từ một họ, nhưng một BST không có nhược điểm này. Ngoài ra, khi áp lực bảng băm tăng quá mức, bạn thường có xu hướng phóng to và phân bổ lại bảng băm, đây có thể là một hoạt động tốn kém. Ở đây, BST có hành vi đơn giản hơn và không có xu hướng đột ngột phân bổ nhiều dữ liệu và thực hiện thao tác băm lại.
Cây có xu hướng là cấu trúc dữ liệu trung bình cuối cùng. Chúng có thể hoạt động như một danh sách, có thể dễ dàng tách ra để hoạt động song song, có thể loại bỏ, chèn và tra cứu nhanh theo thứ tự của O (lg n) . Họ không làm gì đặc biệt tốt, nhưng họ cũng không có bất kỳ hành vi quá xấu nào.
Cuối cùng, các BST dễ dàng triển khai hơn nhiều trong các ngôn ngữ chức năng (thuần túy) so với bảng băm và chúng không yêu cầu thực hiện các cập nhật phá hủy ( đối số bền bỉ của Pascal ở trên).
BSTs are much easier to implement in (pure) functional languages compared to hash-tables
- có thật không? Tôi muốn học một ngôn ngữ chức năng ngay bây giờ!
Ưu điểm chính của cây nhị phân so với bảng băm là cây nhị phân cung cấp cho bạn hai thao tác bổ sung mà bạn không thể thực hiện (dễ dàng, nhanh chóng) với bảng băm
tìm phần tử gần nhất với (không nhất thiết phải bằng) một số giá trị khóa tùy ý (hoặc gần nhất ở trên / dưới)
lặp qua nội dung của cây theo thứ tự đã sắp xếp
Cả hai được kết nối với nhau - cây nhị phân giữ nội dung của nó theo thứ tự được sắp xếp, vì vậy những thứ yêu cầu thứ tự được sắp xếp đó rất dễ thực hiện.
Cây tìm kiếm nhị phân (cân bằng) cũng có ưu điểm là độ phức tạp tiệm cận của nó thực sự là một giới hạn trên, trong khi thời gian "không đổi" cho bảng băm là thời gian được khấu hao: Nếu bạn có một hàm băm không phù hợp, bạn có thể bị giảm xuống thời gian tuyến tính , thay vì hằng số.
Một bảng băm sẽ chiếm nhiều dung lượng hơn khi nó được tạo lần đầu tiên - nó sẽ có các vị trí có sẵn cho các phần tử chưa được chèn (cho dù chúng đã được chèn hay chưa), cây tìm kiếm nhị phân sẽ chỉ lớn như nó cần là. Ngoài ra, khi một bảng băm cần thêm không gian, việc mở rộng sang một cấu trúc khác có thể tốn thời gian, nhưng điều đó có thể phụ thuộc vào việc triển khai.
Cây tìm kiếm nhị phân có thể được thực hiện với một giao diện liên tục , nơi một cây mới được trả về nhưng cây cũ vẫn tiếp tục tồn tại. Được triển khai cẩn thận, cây cũ và cây mới chia sẻ hầu hết các nút của chúng. Bạn không thể làm điều này với một bảng băm tiêu chuẩn.
Một cây nhị phân chậm hơn để tìm kiếm và chèn vào, nhưng có một tính năng rất hay là duyệt infix, về cơ bản có nghĩa là bạn có thể lặp lại qua các nút của cây theo thứ tự được sắp xếp.
Việc lặp đi lặp lại các mục nhập của bảng băm không có ý nghĩa nhiều vì chúng đều nằm rải rác trong bộ nhớ.
Từ bẻ khóa cuộc phỏng vấn mã hóa, ấn bản thứ 6
Chúng ta có thể triển khai bảng băm với cây tìm kiếm nhị phân cân bằng (BST). Điều này cho chúng ta thời gian tra cứu O (log n). Ưu điểm của điều này là có thể sử dụng ít không gian hơn, vì chúng tôi không còn phân bổ một mảng lớn nữa. Chúng ta cũng có thể lặp lại các phím theo thứ tự, điều này đôi khi có thể hữu ích.
Các BST cũng cung cấp các phép toán "findPred Cần thiết" và "findSuccessor" (Để tìm phần tử nhỏ nhất và lớn nhất tiếp theo) trong thời gian O (logn), đây cũng có thể là các hoạt động rất tiện dụng. Bảng băm không thể cung cấp hiệu quả về thời gian đó.
Nếu bạn muốn truy cập dữ liệu theo cách được sắp xếp, thì danh sách đã sắp xếp phải được duy trì song song với bảng băm. Một ví dụ điển hình là Từ điển trong .Net. (xem http://msdn.microsoft.com/en-us/library/3fcwy8h6.aspx ).
Điều này có tác dụng phụ là không chỉ làm chậm các lần chèn mà còn tiêu tốn một lượng bộ nhớ lớn hơn so với cây b.
Hơn nữa, vì cây b được sắp xếp nên việc tìm các dải kết quả hoặc thực hiện hợp nhất hoặc hợp nhất rất đơn giản.
Nó cũng tùy thuộc vào việc sử dụng, Hash cho phép xác định vị trí khớp chính xác. Nếu bạn muốn truy vấn một phạm vi thì BST là sự lựa chọn. Giả sử bạn có rất nhiều dữ liệu e1, e2, e3 ..... vi.
Với bảng băm, bạn có thể xác định vị trí bất kỳ phần tử nào trong thời gian không đổi.
Nếu bạn muốn tìm các giá trị phạm vi lớn hơn e41 và nhỏ hơn e8, BST có thể nhanh chóng tìm thấy điều đó.
Điều quan trọng là hàm băm được sử dụng để tránh va chạm. Tất nhiên, chúng ta hoàn toàn không thể tránh được va chạm, trong trường hợp đó chúng ta phải dùng đến xích hoặc các phương pháp khác. Điều này làm cho việc truy xuất không còn là thời gian liên tục trong những trường hợp xấu nhất.
Sau khi đầy, bảng băm phải tăng kích thước nhóm và sao chép lại tất cả các phần tử. Đây là một chi phí bổ sung không có trong BST.
Bảng băm không tốt cho việc lập chỉ mục. Khi bạn đang tìm kiếm một phạm vi, các BST sẽ tốt hơn. Đó là lý do tại sao hầu hết các chỉ mục cơ sở dữ liệu sử dụng cây B + thay vì Bảng băm
Cây tìm kiếm nhị phân là lựa chọn tốt để triển khai từ điển nếu các khóa có một số thứ tự tổng số (các khóa có thể so sánh được) được xác định trên chúng và bạn muốn bảo toàn thông tin thứ tự.
Vì BST lưu giữ thông tin đơn đặt hàng, nó cung cấp cho bạn bốn hoạt động tập hợp động bổ sung mà không thể thực hiện (hiệu quả) bằng cách sử dụng bảng băm. Các hoạt động này là:
Tất cả các hoạt động này giống như mọi hoạt động BST có độ phức tạp về thời gian là O (H). Ngoài ra, tất cả các khóa được lưu trữ vẫn được sắp xếp trong BST do đó cho phép bạn nhận được chuỗi khóa đã được sắp xếp chỉ bằng cách lướt qua cây theo thứ tự.
Tóm lại, nếu tất cả những gì bạn muốn là thao tác chèn, xóa và loại bỏ thì bảng băm là không thể đánh bại (hầu hết thời gian) về hiệu suất. Nhưng nếu bạn muốn bất kỳ hoặc tất cả các thao tác liệt kê ở trên, bạn nên sử dụng một BST, tốt nhất là BST tự cân bằng.
ưu điểm chính của bảng băm là nó thực hiện hầu hết tất cả các hoạt động trong ~ = O (1). Và nó rất dễ hiểu và thực hiện. Nó giải quyết nhiều "vấn đề phỏng vấn" một cách hiệu quả. Vì vậy, nếu bạn muốn thực hiện một cuộc phỏng vấn viết mã, hãy kết bạn với bảng băm ;-)
Bản đồ băm là một mảng kết hợp tập hợp. Vì vậy, mảng các giá trị đầu vào của bạn được gộp lại thành các nhóm. Trong lược đồ đánh địa chỉ mở, bạn có một con trỏ đến một nhóm và mỗi lần bạn thêm một giá trị mới vào một nhóm, bạn sẽ tìm ra nơi nào trong nhóm có không gian trống. Có một số cách để thực hiện việc này - bạn bắt đầu từ đầu thùng và tăng con trỏ mỗi lần và kiểm tra xem nó có bị chiếm dụng hay không. Đây được gọi là thăm dò tuyến tính. Sau đó, bạn có thể thực hiện tìm kiếm nhị phân như thêm, nơi bạn nhân đôi sự khác biệt giữa điểm bắt đầu của nhóm và nơi bạn tăng gấp đôi hoặc giảm xuống mỗi khi bạn đang tìm kiếm một không gian trống. Đây được gọi là thăm dò bậc hai. ĐỒNG Ý. Bây giờ vấn đề trong cả hai phương pháp này là nếu thùng tràn vào địa chỉ nhóm tiếp theo, thì bạn cần phải-
ĐỒNG Ý. nhưng nếu bạn sử dụng một danh sách liên kết sẽ không có vấn đề như vậy phải không? Có, trong danh sách được liên kết bạn không gặp vấn đề này. Việc xem xét mỗi nhóm để bắt đầu bằng một danh sách được liên kết và nếu bạn có 100 phần tử trong một nhóm, nó yêu cầu bạn duyệt qua 100 phần tử đó để đến cuối danh sách liên kết do đó List.add (Phần tử E) sẽ mất thời gian để-
Ưu điểm của việc triển khai danh sách liên kết là bạn không cần thao tác cấp phát bộ nhớ và chuyển / sao chép O (N) của tất cả các nhóm như trong trường hợp triển khai địa chỉ mở.
Vì vậy, cách để giảm thiểu hoạt động O (N) là chuyển đổi việc triển khai thành của Cây tìm kiếm nhị phân trong đó phép toán tìm là O (log (N)) và bạn thêm phần tử vào vị trí của nó dựa trên giá trị của nó. Tính năng bổ sung của một BST là nó được sắp xếp!
Cây tìm kiếm nhị phân có thể nhanh hơn khi được sử dụng với các phím chuỗi. Đặc biệt là khi dây dài.
Cây tìm kiếm nhị phân sử dụng so sánh cho ít hơn / lớn hơn nhanh hơn đối với các chuỗi (khi chúng không bằng nhau). Vì vậy, một BST có thể nhanh chóng trả lời khi không tìm thấy chuỗi. Khi nó được tìm thấy, nó sẽ chỉ cần thực hiện một phép so sánh đầy đủ.
Trong một bảng băm. Bạn cần tính toán băm của chuỗi và điều này có nghĩa là bạn cần xem qua tất cả các byte ít nhất một lần để tính toán băm. Sau đó, một lần nữa, khi một mục nhập phù hợp được tìm thấy.