Có tồn tại một hàng đợi ưu tiên với chiết xuất không?


46

Có rất nhiều cấu trúc dữ liệu thực hiện giao diện hàng đợi ưu tiên:

  • Chèn: chèn một phần tử vào cấu trúc
  • Get-Min: trả về phần tử nhỏ nhất trong cấu trúc
  • Extract-Min: loại bỏ phần tử nhỏ nhất trong cấu trúc

Các cấu trúc dữ liệu phổ biến thực hiện giao diện này là ( heap ) đống .

Thông thường, thời gian chạy (khấu hao) của các hoạt động này là:

  • Chèn: (đôi khi )O ( log n )O(1)O(logn)
  • Nhận tối thiểu:O(1)
  • Trích xuất tối thiểu:O(logn)

Các đống Fibonacci đạt được những lần chạy ví dụ. Bây giờ, câu hỏi của tôi là như sau:

Có cấu trúc dữ liệu với thời gian chạy (khấu hao) sau đây không?

  • Chèn:O(logn)
  • Nhận tối thiểu:O(1)
  • Trích xuất tối thiểu:O(1)

Nếu chúng ta có thể xây dựng một cấu trúc như vậy trong thời gian đã cho đầu vào được sắp xếp, thì chúng ta có thể tìm giao điểm đường trên các đầu vào được sắp xếp trước với giao cắt nhanh hơn so với nếu chúng ta sử dụng hàng đợi ưu tiên 'thông thường'.o ( nO(n)o(nlogn)


Tôi nghĩ rằng sử dụng BST cân bằng, điều đó sẽ không cân bằng khi thực hiện Extract-Min có thể hoạt động. Hoặc có thể một danh sách bỏ qua.
Svick

@svick: danh sách bỏ qua được chọn ngẫu nhiên, đó không phải là thứ tôi đang tìm kiếm. Nếu bạn có thể làm điều đó với BST, thì thật tuyệt, nhưng tôi nghĩ bạn sẽ phải thực hiện một số cách cân bằng.
Alex ten Brink

Một lưu ý phụ: đây là một câu hỏi gieo hạt và tôi biết câu trả lời, nhưng thật tuyệt khi thấy nó không dễ giải quyết như vậy. Nếu bất cứ ai biết câu trả lời, đừng ngần ngại đưa ra :)
Alex ten Brink

Nếu bạn chấp nhận thời gian cập nhật khấu hao, thì bạn có thể giữ cấu trúc heap tiêu chuẩn của mình và chỉ thực hiện các sửa đổi nhỏ cho phân tích của mình. Xem câu trả lời của tôi dưới đây.
Joe

Câu trả lời:


27

Ý tưởng của chúng tôi là sử dụng cây splay có ren . Khác với bài viết Wikipedia, chúng tôi sẽ xâu chuỗi các cây sao cho mỗi nút có một con trỏ tới người kế thừa theo thứ tự theo thứ tự; chúng ta cũng giữ một con trỏ tới phần tử nhỏ nhất trong cây.nextstart

Dễ dàng thấy rằng trích xuất phần tử nhỏ nhất có thể trong thời gian (trường hợp xấu nhất) : chỉ cần làm theo con trỏ, loại bỏ tối thiểu và thay đổi con trỏ thành tối thiểu . Tối thiểu không bao giờ có thể có một đứa con trái; nếu nó có một đứa con đúng, chúng ta đặt nó ở vị trí tối thiểu trên cây. Chúng tôi không thực hiện các hoạt động splay cây thường chơi. Kết quả là một cây tìm kiếm vẫn cân bằng hợp lý: bởi vì chúng tôi chỉ loại bỏ các nút ở sườn bên trái, chúng tôi biết rằng khi số lượng nút (trong một cây con bị ảnh hưởng) giảm xuống khoảng một nửa số ban đầu do xóa, thì (phụ ) chiều cao của cây bị giảm đi một.O(1)startnext

Việc chèn thêm có thể trong thời gian khấu hao ; các hoạt động zig-zag (và những gì không) ở đây cũng sẽ cân bằng lại cây một cách độc đáo.O(logn)

Đây là một bản phác thảo thô tốt nhất. Tín dụng đến F. Weinberg, người đã đánh đố câu hỏi với tôi và cố vấn của chúng tôi M. Nebel, người đã đề cập đến cây splay, về biến thể cây duy nhất chúng tôi chưa thử.


2
Tôi không rõ làm thế nào để phân tích khấu hao hoạt động nếu bạn không chơi trên extractMin. Bạn có thể cho một gợi ý?
jbapple

Chúng tôi đã không làm điều đó một cách chi tiết. Ý tưởng là một loạt các hoạt động giải nén không làm mất cân bằng cây, do đó không cần thiết phải chơi và phân tích bình thường sẽ hoạt động cho các phần chèn thêm.
Raphael

9
Cẩn thận! Cây Splay không nhất thiết phải cân bằng. Các nút không được truy cập trong một thời gian dài có thể rất sâu trong cây. Để thực hiện phân tích, bạn phải tranh luận về cùng một chức năng tiềm năng được sử dụng để phân tích các mảng.
JeffE

20
  • Chèn:O(logn)
  • Nhận tối thiểu:O(1)
  • Trích xuất tối thiểu:O(1)

Thời gian khấu hao

Việc triển khai đơn giản hàng đợi ưu tiên (ví dụ: bất kỳ BST cân bằng hoặc heap nhị phân tiêu chuẩn) có thể đạt được các thời gian chạy (được khấu hao) này bằng cách tính chi phí của Extract-Min để chèn và duy trì một con trỏ đến phần tử tối thiểu. Ví dụ: bạn có thể có một hàm tiềm năng là . Sau đó, chèn một phần tử mới làm tăng tiềm năng bằng và do đó, chi phí khấu hao của phần chèn vẫn là , nhưng Extract-Min () làm giảm tiềm năng bởi và do đó chi phí khấu hao chỉ là .O ( log n ) O ( log n ) Ω ( log n ) O ( 1 )cnlognO(logn)O(logn)Ω(logn)O(1)

Trường hợp xấu nhất

Bạn có thể sử dụng cấu trúc dữ liệu hiện có trong tài liệu: cây tìm kiếm bằng ngón tay và chỉ cần duy trì một con trỏ đến phần tử tối thiểu. Xem khảo sát này để biết tổng quan và bài báo năm 1988 của Levcopoulos và Overmars để biết phiên bản có thể thực hiện được, đáp ứng nhu cầu của bạn.


1
Làm thế nào rất lén lút. Bạn nói đúng, tôi đoán tôi nên yêu cầu một cái gì đó mạnh mẽ hơn để loại trừ điều này. Ý tưởng hay :)
Alex ten Brink

@AlextenBrink Bạn có thể yêu cầu xóa trường hợp tồi tệ nhất . (dường như là những gì một số câu trả lời khác đang diễn ra) Tôi đã thêm một đoạn vào câu trả lời của mình để giải quyết trường hợp đó. O(1)
Joe

14

2-4 cây đã được khấu hao tại các vị trí đã biết. Điều đó có nghĩa là, nếu bạn có một con trỏ tới một vị trí nào đó trong cây, bạn có thể xóa hoặc thêm một phần tử ở đó trong thời gian khấu hao O ( 1 ) .O(1)O(1)

Do đó, bạn có thể chỉ cần giữ một con trỏ tới phần tử tối thiểu và nút gốc trong cây 2-4. Chèn phải đi qua nút gốc. Cập nhật con trỏ đến mức tối thiểu là không đáng kể sau khi xóaMin và thời gian xóa là thời gian (khấu hao).O(1)

Một lưu ý phụ thú vị: cây đỏ đen chỉ là cách nhìn 2-4 cây. Các nhà thiết kế của những người triển khai thư viện dự kiến ​​tiêu chuẩn C ++ 98 sẽ cung cấp một thùng chứa dựa trên cây đỏ đen và tiêu chuẩn chỉ định rằng việc chèn và xóa phải là thời gian khấu hao tại các vị trí đã biết (mà họ gọi là "iterators" ). Tuy nhiên, điều này thực sự khó khăn hơn nhiều đối với cây đỏ đen so với 2-4 cây, vì nó đòi hỏi các nút đánh dấu lười biếng cần được tô màu lại. Theo hiểu biết của tôi, không có triển khai thư viện chuẩn C ++ 98 nào đáp ứng yêu cầu cụ thể đó.O(1)


8

Theo yêu cầu, đây là cấu trúc tôi tìm thấy sau khi tôi đặt câu hỏi:

Ý tưởng cơ bản là sử dụng cây Scapegoat có ren cùng với một con trỏ đến mức tối thiểu (và để đo tốt, mức tối đa là tốt). Một thay thế đơn giản hơn cho luồng là duy trì con trỏ tiền nhiệm và con trỏ kế tiếp trong mỗi nút (tương đương, đơn giản hơn, nhưng có nhiều chi phí hơn). Tôi đã đến để gọi nó là một đống Scapegoat , chỉ để đặt cho nó một số tên.

Chỉ cấu trúc cơ bản này cung cấp cho bạn các hoạt động sau:

  • Tìm kiếm: được cung cấp một khóa, trả về một con trỏ tới nút tương ứng trong thời gian .O(logn)
  • O(logn)
  • O(1)
  • Get-Min / Max: trả con trỏ về mức tối thiểu hoặc tối đa.

O(logn)O(1)O(logn)O(1)O(1)O(1)

  • O(1)

Kết hợp điều này:

  • O(1)

Bạn có thể làm nhiều hơn một chút với các con trỏ: ví dụ, không khó để duy trì một con trỏ tới trung vị hoặc một số thống kê thứ tự khác, vì vậy bạn có thể duy trì một số lượng con trỏ như vậy nếu bạn cần chúng.

Một số điều khác:

  • Xây dựng: đưa ra khóa theo thứ tự được sắp xếp, xây dựng một đống Scapegoat trong thời gian .O ( n )nO(n)
  • Cân bằng: cân bằng cây để nó tạo thành cây tìm kiếm nhị phân cân bằng hoàn hảo (giảm chi phí tìm kiếm) trong thời gian (bạn có thể thực hiện điều này một yếu tố không đổi nhanh hơn so với đề xuất bằng cách sử dụng của con trỏ tiền nhiệm / kế nhiệm).O(n)

Và cuối cùng, tôi khá chắc chắn rằng bạn có thể hỗ trợ các hoạt động này, nhưng tôi cần suy nghĩ về những điều này nhiều hơn một chút trước khi biết điều này chắc chắn:

  • Chèn-Mới-Tối thiểu / Tối đa: được cung cấp một khóa nhỏ hơn / lớn hơn bất kỳ khóa nào đã có trong cấu trúc, chèn khóa vào cấu trúc, trả về một con trỏ tới nút đó trong thời gian .O(1)

Cái nhìn sâu sắc quan trọng là cây scapegoat đảm bảo với bạn rằng việc xóa bất kỳ nút nào mà không cân bằng lại không ảnh hưởng đến hiệu suất của các hoạt động khác trong thời gian dài, ngay cả khi bạn xóa nhiều nút.
Raphael

O(lgn)O(1)O(lgn)

2
O(1)O(1)O(1)O(1)
Alex ten Brink

À, giờ thì tôi đã hiểu.
jbapple

2

ϵO(1)log(1/ϵ)ϵ

ϵn

Đối với bài viết gốc, rõ ràng và được viết độc đáo, xem Bernard Chazelle, The Soft Heap: Một hàng đợi ưu tiên gần đúng với tỷ lệ lỗi tối ưu, Tạp chí ACM, 47 (6), trang 1012-1027, 2000 . Để thực hiện thay thế và phân tích tuyên bố đơn giản và trực quan hơn từ SODA'09, hãy xem Kaplan H. & Zwick U., Một triển khai và phân tích đơn giản hơn về đống mềm của Chazelle, 2009 .


Mặc dù cơ sở hạ tầng rất thú vị, các đống mềm không chính xác: findmin có thể trả về một giá trị không phải là tối thiểu, mà chỉ là một mức tối thiểu gần đúng. Dù sao cũng cảm ơn các liên kết :)
Alex ten Brink

1
@AlextenBrink: điểm của cấu trúc dữ liệu (giống như nhiều thuật toán xác suất) là bạn có thể sử dụng cấu trúc dữ liệu gần đúng để có câu trả lời chính xác. Thật vậy, bản chất gần đúng của các đống mềm không ngăn nó được sử dụng trong thuật toán thời gian tuyến tính duy nhất được biết đến cho cây bao trùm tối thiểu.
Jérémie

2

Được rồi, cuối cùng đã cho bạn thấy sự phức tạp mà bạn đang tìm kiếm, và điều tốt nhất, tôi đã tìm thấy nó trong tài liệu:

Phức tạp trường hợp xấu nhất

O(1)

O(1)

O(1)

O(log n)

Tài liệu tham khảo

[3]O(1)O(log n)O(n)

Brodal, Gerth Stølting. "Hàng đợi ưu tiên có thể kết hợp nhanh". Trong Kỷ yếu của Hội thảo quốc tế lần thứ 4 về Thuật toán và Cấu trúc dữ liệu, 282 chiếc290. ÁO '95. Luân Đôn, Anh, Anh: Springer-Verlag, 1995.

[3]: Dietz, Paul F và Rajeev Raman. 'Một cây tìm kiếm thời gian cập nhật liên tục'. Thư xử lý thông tin 52, không. 3 (1994): 147 - 154.

Mặc dù điều này sử dụng mô hình tính toán RAM :

Cấu trúc dữ liệu của chúng tôi sử dụng mô hình máy truy cập ngẫu nhiên (RAM) với thước đo đơn giá và kích thước từ logarit;

Gần đây, một mô hình giải pháp tính toán con trỏ máy đã được đưa ra [1].

[1]: Brodal, Gerth Stølting, George Lagogianni, Christos Makris, Athanasios Tsakalidis, và Kostas Tsichlas. 'Cây tìm kiếm ngón tay tối ưu trong máy con trỏ'. J. Tính toán. Hệ thống. Khoa học. 67, không 2 (Tháng 9/2003): 381 Vang418.


2

Tiếp cận vấn đề này bằng cách duy trì hai cấu trúc dữ liệu: Mảng và Cây nhị phân.

Ω(lognloglogn)Ω(logn)

O(logn)O(logn)

nullO(logn)

O(1)O(1)

O(logn)O(1)delete_at(idx)


1 Patrascu, Mihai và Erik D. Demaine. Giới hạn dưới logarit trong mô hình thăm dò tế bào. SI SIAM J. Comput. 35, không 4 (Tháng 4 năm 2006): 932 Từ963. doi: 10.1137 / S0097539705447256.


1
O(logn)

"Luồng cây tìm kiếm nhị phân thành một mảng" nghĩa là gì?
jbapple

@AT: Tôi chia sẻ tình cảm của jbapple.
Raphael

Ω(k)kO(1)

Bản cập nhật của bạn, trong đó bạn giải thích cách thực hiện các phép quay trong thời gian không đổi, không hoạt động trong các mảng. Câu trả lời này vẫn không chính xác. Bài báo Tarjan mà bạn tham khảo là về các cây được lưu trữ với các nút và con trỏ.
jbapple

-2

O(1)O(log log n)

Xem bài viết năm 2007: Sự tương đương giữa các hàng đợi ưu tiên và sắp xếp của Mikkel Thorup.

O(n log log n)


Mặc dù bài báo bạn liên kết rất thú vị, hàng đợi ưu tiên mà họ trình bày không bị xóa thời gian liên tục (nếu tôi đọc tóm tắt chính xác), và do đó không phải là điều tôi đang yêu cầu.
Alex ten Brink

-2

Phân tích

o(n log log n)

o(log log n)

O(1)

O(n)

O(1)

O(1)

Thực hiện

  1. O(1)
  2. O(6)O(1)
  3. k±
    ((k>nsize1)(k<n0)((k<ni)(k>ni+1)))
    o(log log n)

[1]: Andersson, Arne và Christer Mattsson. 'Tìm kiếm nội suy động trong O (log log n) Time'. Trong Automata, Ngôn ngữ và Lập trình, được chỉnh sửa bởi Andrzej Lingas, Rolf Karlsson và Svante Carlsson, 700: 15 Phản27. Bài giảng trong khoa học máy tính. Springer Berlin / Heidelberg, 1993. http://dx.doi.org/10.1007/3-540-56939-1_58 .


2
Vâng, thời gian chèn là cách ra khỏi nhãn hiệu.
Raphael

nsize1n0nini+1

Đọc tóm tắt của bài báo mà bạn liên kết, có vẻ như các giới hạn này là giới hạn dự kiến ​​cho các đầu vào của một phân phối cụ thể, do đó không phải là điều tôi đang tìm kiếm: Tôi muốn các giới hạn tôi đề cập đến bất kỳ đầu vào nào.
Alex ten Brink

O(log n)

@AT Tìm kiếm nhị phân logarit cần truy cập ngẫu nhiên. Danh sách cơ bản được thực hiện là gì? Bạn nên thực sự tranh luận cho giới hạn yêu cầu của bạn. Ngoài ra, "các vị trí trong danh sách" còn mơ hồ - vị trí nào và các biểu tượng đề cập đến điều gì? Không phải ai cũng có quyền truy cập vào bài báo mà bạn liên kết. Hãy cố gắng làm cho câu trả lời của bạn (nhiều hơn) khép kín và ít nhất là tóm tắt các sự kiện. Tại thời điểm này tôi không tin câu trả lời của bạn là chính xác.
Juho
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.