Có thể tăng tốc bảng băm bằng cách sử dụng các cây tìm kiếm nhị phân cho chuỗi riêng biệt không?


11

Tôi muốn triển khai Bảng Hash bằng cách sử dụng Cây tìm kiếm nhị phân để giảm độ phức tạp tìm kiếm trong quy trình Xâu chuỗi riêng biệt từ O (n) (sử dụng danh sách được liên kết) đến O (log n) (sử dụng BST). Điều này có thể được thực hiện, và nếu có thì làm thế nào? Sẽ dễ hiểu hơn nếu giải pháp từng bước, thực hiện logic.

Tôi muốn giảm thời gian Tìm kiếm trong hashtable (xây dựng bằng cách sử dụng chuỗi riêng), nhưng đồng thời tôi không muốn thời gian chèn tăng lên. Đối với dự án của tôi, tôi không thể thay đổi hàm băm để giảm va chạm. Nhưng do khả năng mở rộng, va chạm đang xảy ra. Tôi đang cố gắng tìm một công việc xung quanh, để bằng cách nào đó tôi có thể làm việc với quyền truy cập và chèn thời gian tốt nhất trong trường hợp xảy ra va chạm ... tức là để quản lý trạng thái hiện tại của mọi thứ hơn là cơ cấu lại toàn bộ thuật toán. Nếu nó không pan ra thì sẽ phải cơ cấu lại. Vậy có ý kiến ​​gì không?


4
Bảng băm và Cây tìm kiếm nhị phân là các thùng chứa khác nhau . Vì vậy, bạn không thể làm những gì bạn đề xuất (hoặc bạn đang mắc một lỗi thuật ngữ).
Basile Starynkevitch

Tôi đoán bạn có thể đặt một cặp băm / giá trị trong mỗi nút trong một cây ... nhưng đó sẽ là bảng băm xấu hoặc cây nhị phân xấu. Không có một số giải thích rõ ràng về lý do tại sao bạn muốn làm điều này và những gì bạn muốn kết quả cuối cùng có khả năng, tôi không chắc điều này thực sự có thể trả lời được.
Ixrec

1
@AK_: Yup một cái gì đó thuộc loại đó, như bạn đã nói. tôi muốn xử lý các va chạm bằng cây tìm kiếm nhị phân. tôi đã sửa câu hỏi của mình một chút để làm cho nó rõ ràng hơn.
Avirus

1
Lưu ý rằng đi kèm với hình phạt của O (n log n) cho mỗi lần chèn sau đó. Nói chung, khi bạn có một bảng băm bắt đầu quá đầy (và bạn có chuỗi dài hơn mức bạn có thể chịu đựng), bạn xây dựng lại hàm băm. Nếu bạn thường xuyên gặp phải chuỗi dài hơn 3 hoặc 4, có gì đó không ổn.

3
vô số biến thể trên bảng băm để giảm va chạm, địa chỉ mở và thay đổi kích thước động của bảng. Cái nào phù hợp với yêu cầu của bạn là thứ bạn cần xem xét. Cách tiếp cận hiện tại của bạn được bảo vệ theo chuỗi riêng biệt với các cấu trúc khác

Câu trả lời:


11

Những gì bạn đang yêu cầu là có thể đưa ra các ràng buộc của bạn.

Phân tích

Điểm mạnh của bảng băm là tốc độ tra cứu và chèn nhanh. Để có được tốc độ đó, người ta phải từ bỏ bất kỳ giao dịch nào trong bảng: tức là các mục nhập đều bị xáo trộn. Một danh sách được chấp nhận để sử dụng làm mục nhập bảng vì trong khi truyền tải là O (n), các danh sách có xu hướng ngắn giả sử bảng băm đủ lớn và các đối tượng được lưu trữ trong bảng được băm bằng thuật toán băm chất lượng tốt.

Cây tìm kiếm nhị phân (BST) có chức năng chèn và tra cứu nhanh tại O (log 2 n). Nó cũng áp đặt một hạn chế đối với các yếu tố mà nó lưu trữ: phải có một số cách để đặt hàng các yếu tố. Cho hai phần tử AB được lưu trữ trong cây, có thể xác định xem A đến trước B hay chúng có thứ tự tương đương.

Bảng băm áp đặt không hạn chế như vậy: các phần tử trong bảng băm phải có hai thuộc tính. Đầu tiên, phải có một cách để xác định xem chúng có tương đương không; thứ hai, phải có một cách để tính mã băm xác định. Đặt hàng không phải là một yêu cầu.

Nếu các thành phần bảng băm của bạn có một đơn đặt hàng, thì bạn có thể sử dụng BST làm mục nhập bảng băm để giữ các đối tượng có cùng mã băm (va chạm). Tuy nhiên, do BST có tra cứu và chèn O (log 2 n), điều đó có nghĩa là trường hợp xấu nhất cho toàn bộ cấu trúc (bảng băm cộng với BST) về mặt kỹ thuật tốt hơn so với sử dụng danh sách làm mục nhập bảng. Tùy thuộc vào việc thực hiện BST, nó sẽ yêu cầu nhiều dung lượng hơn một danh sách, nhưng có thể không nhiều hơn.

Xin lưu ý rằng thông thường, chi phí hoạt động và hành vi của BST không mang lại điều gì cho bảng trong các tình huống trong thế giới thực như các thùng bảng băm, đó là lý do tại sao hiệu suất kém về mặt lý thuyết của danh sách có thể chấp nhận được. Nói cách khác, bảng băm bù cho điểm yếu của danh sách bằng cách đặt ít mục hơn trong mỗi danh sách (nhóm). Tuy nhiên : vấn đề được nêu cụ thể là bảng băm không thể tăng kích thước và va chạm thường xuyên hơn so với điển hình trong bảng băm.

Thực hiện

Tôi sẽ không đặt mã ở đây vì thật lòng nó không thực sự cần thiết và dù sao bạn cũng không đưa ra một ngôn ngữ nào.

Những gì tôi sẽ làm chỉ đơn giản là sao chép bất kỳ bảng băm tiêu chuẩn nào mà thư viện tiêu chuẩn của ngôn ngữ của bạn chứa vào một lớp mới, sau đó thay đổi loại nhóm bảng từ danh sách thành cây. Tùy thuộc vào ngôn ngữ và thư viện tiêu chuẩn của nó, đây có thể là một việc rất nhỏ.

Thông thường tôi sẽ không ủng hộ việc sao chép và dán mã hóa như thế này. Tuy nhiên, đây là một cách dễ dàng để có được cấu trúc dữ liệu được thử nghiệm rất nhanh.


Theo thuật ngữ tiệm cận, sử dụng cây nhị phân để xử lý va chạm không làm thay đổi hiệu suất dự kiến ​​của bảng băm với điều kiện là bảng băm đã thực hiện các thủ thuật thông thường để đạt được hiệu suất O (1) được khấu hao. Thay đổi kích thước hashtable để đảm bảo hiệu suất tốt có nghĩa là các mục dự kiến ​​trên mỗi nhóm (kích thước của cây nhị phân) cũng được dự kiến ​​là nhỏ, do đó, bạn kết thúc với cùng một khoản khấu hao O (1) dự kiến. Ngay cả trong trường hợp xấu nhất - không có bất kỳ ràng buộc cân bằng nào được chỉ định, hiệu suất trường hợp xấu nhất đối với cây nhị phân là cuối cùng nó vẫn hoạt động như một danh sách được liên kết.
Steve314

@ Steve314 Hãy nhớ rằng vấn đề là có rất nhiều va chạm, vì vậy anh ta hy vọng một cái xô chứa nhiều vật phẩm hơn một bảng băm thông thường.

Điểm hay - ví dụ: đối với bảng băm có kích thước không đổi với dữ liệu không bị ràng buộc, hiệu suất tiệm cận của bảng băm giống như hiệu suất tiệm cận của xử lý va chạm - bảng băm chỉ thay đổi các yếu tố không đổi.
Steve314

@ Steve314 đúng, về cơ bản nếu bảng băm không thể giới hạn hiệu quả số lượng phần tử trong mỗi nhóm, hiệu suất tiệm cận sẽ giảm xuống thành bất kỳ cấu trúc dữ liệu phụ nào được sử dụng trong mỗi nhóm. Tôi đã thêm một đoạn vào câu trả lời của tôi để làm rõ điều này.

7

Sử dụng cây nhị phân để xử lý va chạm trong bảng băm không thể thực hiện được - nó đã được thực hiện.

Walter Bright được biết đến như là người phát minh ra ngôn ngữ lập trình D , nhưng cũng đã viết một biến thể ECMAScript gọi là DMDScript . Trước đây, một yêu cầu tiêu đề của DMDScript (hoặc có thể là tổ tiên - tôi dường như nhớ tên DScript) là các hashtag của nó có xu hướng vượt trội hơn so với các ngôn ngữ tương tự. Lý do - xử lý va chạm bằng cây nhị phân.

Tôi không nhớ chính xác nơi này đến từ đâu, nhưng những cây được sử dụng là cây nhị phân ngây thơ, không có sơ đồ cân bằng một phần (không phải AVL, đỏ-đen hoặc bất cứ thứ gì) có nghĩa là giả sử chính hashtable bị thay đổi kích thước khi nó bị quá tải và bạn không nhận được tỷ lệ va chạm băm vô lý, cây nhị phân phải luôn nhỏ. Về cơ bản, trường hợp xấu nhất vẫn giống như sử dụng danh sách được liên kết để xử lý va chạm (ngoại trừ bạn trả giá hai con trỏ cho mỗi nút thay vì một) nhưng trường hợp trung bình làm giảm lượng tìm kiếm trong mỗi nhóm băm.

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.