11

Tôi có một bộ sưu tập các mặt hàng (hợp lý lớn) mà tôi sẽ được xử lý. Trong mỗi trường hợp, quá trình xử lý sẽ bao gồm việc xóa mục nhỏ nhất trong bộ sưu tập, thực hiện một số công việc và sau đó thêm 0-2 mục mới (sẽ luôn lớn hơn mục đã xóa). Bộ sưu tập sẽ được khởi tạo với một mục và công việc sẽ tiếp tục cho đến khi nó trống. Tôi không chắc chắn kích thước bộ sưu tập có khả năng đạt được, nhưng tôi mong đợi trong phạm vi các mục 1M-100M. Tôi sẽ không cần phải tìm bất kỳ mục nào khác ngoài mục nhỏ nhất.Cây đỏ đen có phải là cấu trúc dữ liệu lý tưởng của tôi không?

Tôi hiện đang có kế hoạch sử dụng cây đỏ đen, có thể được điều chỉnh để giữ con trỏ đến mục nhỏ nhất. Tuy nhiên tôi chưa bao giờ sử dụng một cái trước đây, và tôi không chắc liệu mô hình sử dụng của tôi có phù hợp với đặc điểm của nó hay không.

1) Có nguy cơ khi xóa mô hình chèn trái + ngẫu nhiên sẽ ảnh hưởng đến hiệu suất, ví dụ bằng cách yêu cầu số lần quay cao hơn đáng kể so với xóa ngẫu nhiên? Hoặc sẽ xóa và chèn các hoạt động vẫn là O (log n) với mẫu sử dụng này?

2) Một số cấu trúc dữ liệu khác sẽ cho tôi hiệu suất tốt hơn, do mô hình xóa hoặc lợi dụng thực tế tôi chỉ cần tìm mục nhỏ nhất?

Cập nhật: vui lòng tôi hỏi, đống nhị phân rõ ràng là giải pháp tốt hơn cho trường hợp này, và như đã hứa hóa ra rất dễ thực hiện.

Hugo

+0

Trừ khi bạn biết chắc chắn rằng các nút bị xóa theo logic sẽ không cần thiết bởi các giá trị mới được tính toán, bạn có thể muốn bỏ qua hoặc trì hoãn xóa. Một cách tiếp cận Halt & Sweep nên làm việc cho sau này, nơi mà rễ của cây phụ đã nhận được quá lộn xộn được truy cập bởi các mã tái cân bằng để cân bằng en'masse. Điều này ngăn ngừa thoái hóa tổng thể, trong khi vẫn cung cấp triển vọng có khả năng về hiệu suất xóa ít hơn. – RocketRoy

Trả lời

12

A binary heap tốt hơn rất nhiều cho những gì bạn muốn. Việc triển khai và nhanh hơn dễ dàng hơn vì bạn chỉ quan tâm đến việc xác định phần tử nhỏ nhất và chèn vào. Định vị phần tử nhỏ nhất là O (1), loại bỏ nó là O (log N), và chèn cũng là O (log N).

+0

thực sự, nếu anh ta biết anh ta luôn chèn một mục lớn hơn cái đã loại bỏ, một đống nhị phân (treap) sẽ kết thúc là rất không cân bằng tại một thời điểm. 100M bản ghi là rất nhiều, do đó, điều này có thể nhận được không cân bằng đủ để nó không còn O (log (n)), mà là O (n) - ví dụ, nếu chiều cao của treap kết thúc là 160k khi n = 100M, thì đó là O (n/((lgn)^2)) – Etai

+0

@Etai - một đống nhị phân luôn luôn là 'O (log N)' cho các hoạt động tôi đã đề cập. Tôi không biết tại sao bạn đề cập đến treaps, câu trả lời của tôi đề cập đến heaps nhị phân, không treaps. Heaps thực sự đóng một vai trò trong cấu trúc của treaps, nhưng hai là cấu trúc dữ liệu khác nhau. – IVlad

+0

Chèn heap nhị phân là 'O (1)' trung bình (trường hợp xấu nhất cho Brodal), và đó là lý do chính để sử dụng nó trên BST: http://stackoverflow.com/a/29548834/895245 –

5

Một đống sẽ cung cấp cho bạn O (1) O (log n) loại bỏ và O (log n) chèn, và là nhiều dễ thực hiện hơn so với một cây đỏ-đen

+3

Trên thực tế, loại bỏ là O (log N), ** định vị (tìm giá trị) ** tối thiểu/tối đa là O (1). – IVlad

+0

Tôi chưa bao giờ thấy một đống với các mục 1M-100M trong đó, có ai có một số thông tin về cách ảnh hưởng đến tốc độ của nó không? –

+3

@NickLarsen: đó chính là ý nghĩa của Big-O. –

1

Bạn nên biết cách tạo cấu trúc dữ liệu phức tạp hơn nếu cần. Tuy nhiên, nói chung đặt cược tốt nhất của bạn là bắt đầu đơn giản như bạn có thể, và chỉ sử dụng một cái gì đó phức tạp hơn khi nó quay ra bạn cần.

Thời gian duy nhất tôi từng thực hiện một cây tự cân bằng là một lần khi tôi tình cờ biết rằng cây của tôi sẽ rất lớn (hơn 10.000 nguyên tố), và dữ liệu sẽ đi vào những nhánh được sắp xếp. Điều đó có nghĩa là nếu tôi đã sử dụng một cây nhị phân bình thường, tôi sẽ kết thúc với gần như một danh sách liên kết.

Nếu dữ liệu của bạn được nhập theo thứ tự ngẫu nhiên, bạn thực sự không nên bận tâm với thuật toán cân bằng.

+0

Đồng ý chung về KISS đầu tiên và phức tạp chỉ khi cần thiết. Có nhiều cách để giải quyết yêu cầu tự cân bằng, chẳng hạn như tạo chỉ mục để đọc dữ liệu theo thứ tự ngẫu nhiên, nhưng báo trước là điều này chỉ hoạt động nếu bạn biết yêu cầu. IE: không dùng cho mục đích chung, như tạo thư viện. Cũng rất xấu nghi thức để lại công việc này cho một số khốn nghèo người đã duy trì mã của bạn sau này. Điều đó nói rằng, tôi thường đồng ý với triết lý của bạn. – RocketRoy

Các vấn đề liên quan