Toàn bộ chuyên luận có thể được viết về chủ đề này; Tôi sẽ chỉ đề cập đến một số điểm nổi bật và tôi sẽ giữ cho cuộc thảo luận về các cấu trúc dữ liệu khác ở mức tối thiểu (thực sự có nhiều biến thể). Trong suốt câu trả lời này, là số lượng khóa trong từ điển.n
Câu trả lời ngắn gọn là các bảng băm nhanh hơn trong hầu hết các trường hợp , nhưng có thể rất tệ ở mức tồi tệ nhất của chúng. Cây tìm kiếm có nhiều lợi thế, bao gồm hành vi trong trường hợp xấu nhất , nhưng có phần chậm hơn trong các trường hợp điển hình.
Cây tìm kiếm nhị phân cân bằng có độ phức tạp khá thống nhất: mỗi phần tử có một nút trong cây (thường là 4 từ bộ nhớ), và các thao tác cơ bản (tra cứu, chèn, xóa) mất thời gian (đảm bảo giới hạn trên tiệm cận). Chính xác hơn, một truy cập trong cây mất khoảng so sánh .O ( l g ( n ) )l o g2( n )
Bảng băm là một chút thay đổi. Họ yêu cầu một mảng khoảng con trỏ. Truy cập vào một yếu tố phụ thuộc vào chất lượng của hàm băm. Mục đích của hàm băm là phân tán các phần tử. Một bảng băm có tác dụng nghiêm trọng nếu tất cả các yếu tố bạn muốn lưu trữ trong đó có các giá trị băm khác nhau. Nếu đây là trường hợp, thì các thao tác cơ bản (tra cứu, chèn, xóa) mất thời gian , với hằng số khá nhỏ (một phép tính băm cộng với một lần tra cứu con trỏ). Điều này làm cho bảng băm rất nhanh trong nhiều trường hợp điển hình.2 nÔ ( 1 )
Một vấn đề chung với các bảng băm là độ phức tạp không được đảm bảo.Ô ( 1 )
- Ngoài ra, có một điểm mà bảng trở nên đầy đủ; khi điều đó xảy ra (hoặc, tốt hơn, một chút trước khi điều đó xảy ra), bảng cần được mở rộng, đòi hỏi phải di chuyển tất cả các phần tử của nó, với chi phí . Điều này có thể giới thiệu hành vi giật giật của Hồi giáo khi có rất nhiều yếu tố được thêm vào.Ô ( n )
- Đầu vào có thể va chạm vào một vài giá trị băm. Điều này hiếm khi xảy ra một cách tự nhiên, nhưng nó có thể là một vấn đề bảo mật nếu đầu vào được chọn bởi kẻ tấn công: đó là cách để làm chậm đáng kể một số máy chủ. Vấn đề này đã khiến một số triển khai ngôn ngữ lập trình (như Perl và Python) chuyển từ bảng băm cũ đơn giản sang hàm băm liên quan đến một số ngẫu nhiên được chọn khi bảng băm được xây dựng, cùng với hàm băm lan truyền tốt dữ liệu ngẫu nhiên này (làm tăng hằng số nhân trong ) hoặc đến cây tìm kiếm nhị phân. Mặc dù bạn có thể tránh va chạm bằng cách sử dụng hàm băm mật mã, nhưng điều này không được thực hiện trong thực tế vì băm mật mã tương đối chậm để tính toán.Ô ( 1 )
Khi bạn ném dữ liệu cục bộ vào hỗn hợp, các bảng băm hoạt động kém. Chúng hoạt động chính xác vì chúng lưu trữ các phần tử liên quan cách xa nhau, điều đó có nghĩa là nếu ứng dụng tìm kiếm các phần tử chia sẻ tiền tố theo trình tự, nó sẽ không được hưởng lợi từ các hiệu ứng bộ đệm. Điều này không liên quan nếu ứng dụng thực hiện tra cứu ngẫu nhiên.
Một yếu tố khác có lợi cho cây tìm kiếm là chúng là một cấu trúc dữ liệu bất biến : nếu bạn cần lấy một bản sao của cây và thay đổi một vài yếu tố trong đó, bạn có thể chia sẻ hầu hết cấu trúc dữ liệu. Nếu bạn lấy một bản sao của bảng băm, bạn cần sao chép toàn bộ mảng con trỏ. Ngoài ra, nếu bạn đang làm việc trong một ngôn ngữ chức năng thuần túy, bảng băm thường không phải là một tùy chọn.
Khi bạn vượt ra ngoài chuỗi, bảng băm và cây tìm kiếm nhị phân đưa ra các yêu cầu khác nhau về kiểu dữ liệu của khóa: bảng băm yêu cầu hàm băm (hàm từ khóa đến số nguyên sao cho , trong khi cây tìm kiếm nhị phân yêu cầu tổng thứ tự. Đôi khi, băm có thể được lưu vào bộ đệm, nếu có đủ chỗ trong cấu trúc dữ liệu nơi khóa được lưu trữ, lưu trữ kết quả so sánh (hoạt động nhị phân) thường không thực tế. Mặt khác, các so sánh có thể được hưởng lợi từ việc rút ngắn: nếu các khóa thường khác nhau trong một vài byte đầu tiên, thì so sánh âm có thể rất nhanh.k1≡ k2⟹h ( k1) = h ( k2)
Cụ thể, nếu bạn sẽ cần thứ tự trên các phím, ví dụ nếu bạn muốn có thể liệt kê các khóa theo thứ tự bảng chữ cái, thì bảng băm không có ích (bạn sẽ cần sắp xếp chúng), trong khi bạn có thể đi thẳng qua một cây tìm kiếm theo thứ tự.
Bạn có thể kết hợp cây tìm kiếm nhị phân và bảng băm dưới dạng cây băm . Cây băm lưu trữ các khóa trong cây tìm kiếm theo hàm băm của chúng. Điều này rất hữu ích, ví dụ, trong một ngôn ngữ lập trình chức năng thuần túy, nơi bạn muốn làm việc trên dữ liệu không có mối quan hệ thứ tự dễ tính toán.
Khi các phím là chuỗi (hoặc số nguyên), một Trie có thể tùy chọn khác. Trie là một cây, nhưng được lập chỉ mục khác với cây tìm kiếm: bạn viết khóa ở dạng nhị phân và sang trái là 0 và phải cho 1. Chi phí của một truy cập do đó tỷ lệ thuận với độ dài của khóa. Tries có thể được nén để loại bỏ các nút trung gian; cây này được gọi là cây patricia trie hoặc cây radix . Cây Radix có thể vượt trội hơn cây cân bằng, đặc biệt khi nhiều khóa chia sẻ tiền tố chung.