Có một đống ổn định?


32

Có cấu trúc dữ liệu hàng đợi ưu tiên hỗ trợ các hoạt động sau không?

  • Chèn (x, p) : Thêm bản ghi mới x với mức độ ưu tiên p
  • StableExtractMin () : Trả lại và xóa bản ghi với mức độ ưu tiên tối thiểu, phá vỡ các mối quan hệ bằng cách chèn thứ tự .

Do đó, sau khi Chèn (a, 1), Chèn (b, 2), Chèn (c, 1), Chèn (d, 2), một chuỗi StableExtractMin sẽ trả về a, rồi c, rồi b, rồi d.

Rõ ràng người ta có thể sử dụng bất kỳ cấu trúc dữ liệu hàng đợi ưu tiên nào bằng cách lưu trữ cặp làm ưu tiên thực tế, nhưng tôi quan tâm đến cấu trúc dữ liệu không lưu trữ rõ ràng thời gian chèn (hoặc thứ tự chèn), bằng cách tương tự để phân loại ổn định.(p,time)

Tương đương (?): Có phiên bản heapsort ổn định không cần thêm không gian không?Ω(n)


Tôi nghĩ bạn có nghĩa là "a, sau đó c, sau đó b, sau đó d"?
Ross Snider

Heap với danh sách các bản ghi được liên kết + cây nhị phân cân bằng được khóa theo mức độ ưu tiên trỏ đến danh sách được liên kết tương ứng sẽ không hoạt động? Tôi đang thiếu gì?
Aryabhata

Moron: Đó là lưu trữ thứ tự chèn một cách rõ ràng, đó chính xác là điều tôi muốn tránh. Tôi đã làm rõ tuyên bố vấn đề (và sửa lỗi chính tả của Ross).
Jeffε

Câu trả lời:


16

Phương pháp Bently-Saxe cho hàng đợi ưu tiên ổn định khá tự nhiên.

A0,,AkAi2iciAi[ci],,Ai[2i1]

iAiAi+1AiAiAi+1Ai+1

xiAiA0,,Ai1xAic0,,ci

iAi[ci]ici

O(logn)

nnO(logn)Ω(n)

nn

Ak,,A0AkAk1nniAi2i

nA0,,Ai

ciAici2ici1O(logn)A0[0],,Ak[0]Ai[0]Ai[0]AiAi[ci]Ai[0]Ai[ci]

n


1
Điều này sử dụng không gian có khả năng O (n) tại một thời điểm nhất định sau khi trích xuất O (n), không? Tại thời điểm này, bạn cũng có thể lưu trữ mức độ ưu tiên ...
Mehrdad

10

Tôi không chắc chắn những hạn chế của bạn là gì; sau đây có đủ điều kiện? Lưu trữ dữ liệu trong một mảng, mà chúng tôi hiểu là cây nhị phân ẩn (như một đống nhị phân), nhưng với các mục dữ liệu ở cấp độ dưới cùng của cây chứ không phải tại các nút bên trong của nó. Mỗi nút bên trong của cây lưu trữ các giá trị nhỏ hơn được sao chép từ hai con của nó; trong trường hợp quan hệ, sao chép con trái.

Để tìm mức tối thiểu, hãy nhìn vào gốc của cây.

Để xóa một phần tử, đánh dấu nó là đã xóa (xóa lười biếng) và truyền lên cây (mỗi nút trên đường dẫn đến gốc chứa một bản sao của phần tử đã xóa nên được thay thế bằng một bản sao của phần tử con khác). Duy trì số lượng phần tử bị xóa và nếu nó trở nên quá lớn, một phần nhỏ của tất cả các phần tử thì xây dựng lại cấu trúc giữ trật tự của các phần tử ở mức dưới cùng - việc xây dựng lại mất thời gian tuyến tính để phần này chỉ thêm thời gian khấu hao không đổi vào độ phức tạp hoạt động.

Để chèn một phần tử, thêm nó vào vị trí miễn phí tiếp theo trên hàng dưới cùng của cây và cập nhật đường dẫn đến thư mục gốc. Hoặc, nếu hàng dưới cùng đầy, tăng gấp đôi kích thước của cây (một lần nữa với đối số khấu hao; lưu ý rằng phần này không khác gì so với nhu cầu xây dựng lại khi một nhị phân chuẩn vượt quá mảng của nó).

Tuy nhiên, đây không phải là câu trả lời cho câu hỏi chặt chẽ hơn của Mihai bởi vì nó sử dụng bộ nhớ gấp đôi so với cấu trúc dữ liệu ngầm thực sự, ngay cả khi chúng ta bỏ qua chi phí không gian để xử lý xóa một cách lười biếng.


Tôi thích điều này. Giống như với một cây ẩn nhỏ thông thường, có lẽ cây ẩn 3-ary hoặc 4-ary sẽ nhanh hơn vì hiệu ứng bộ đệm (mặc dù bạn cần so sánh nhiều hơn).
Jonathan Graehl

8

Đây có phải là một cách giải thích hợp lệ cho vấn đề của bạn:

Bạn phải lưu trữ N khóa trong một mảng A [1..N] không có thông tin phụ trợ để bạn có thể hỗ trợ: * chèn phím * xóa min, chọn phần tử được chèn sớm nhất nếu có nhiều cực tiểu

Điều này có vẻ khá khó khăn, do hầu hết các cấu trúc dữ liệu ngầm đều chơi trò lừa các bit mã hóa theo thứ tự cục bộ của một số phần tử. Ở đây nếu nhiều kẻ bằng nhau, thứ tự của họ phải được giữ nguyên, vì vậy không có thủ đoạn nào như vậy có thể.

Hấp dẫn.


1
Tôi nghĩ rằng đây nên là một bình luận, không phải là một câu trả lời, vì nó không thực sự trả lời câu hỏi ban đầu. (Bạn có thể xóa nó và thêm nó dưới dạng một nhận xét.)
Jukka Suomela

5
Vâng, trang web này là một chút vô lý. Chúng tôi có danh tiếng, tiền thưởng, phần thưởng, tất cả các cách để nhận xét mà tôi không thể tìm ra. Tôi ước điều này sẽ trông giống như một trò chơi của trẻ em.
Mihai

1
Tôi nghĩ rằng anh ấy cần nhiều đại diện hơn để gửi bình luận. đó chính là vấn đề.
Suresh Venkat

@Suresh: Ồ, đúng rồi, tôi không nhớ điều đó. Làm thế nào chúng ta thực sự phải xử lý loại tình huống này (nghĩa là, một người dùng mới cần yêu cầu làm rõ trước khi trả lời một câu hỏi)?
Jukka Suomela

2
ko có lối thoát dễ dàng. Tôi đã thấy điều này thường xuyên trên MO. Mihai sẽ không gặp khó khăn gì trong việc giành được đại diện, nếu đó là Mihai tôi nghĩ là vậy :)
Suresh Venkat

4

Câu trả lời ngắn gọn: Bạn không thể.

Câu trả lời dài hơn một chút:

Ω(n)Ω(n)

addr(X)<addr(Y)


Câu trả lời rất dài với giả toán không chính xác:

Lưu ý: phần cuối của phần thứ hai là sơ sài, như đã đề cập. Nếu một số người toán học có thể cung cấp một phiên bản tốt hơn, tôi sẽ rất biết ơn.

P

(a,1)<(a,2)(a,1)=(a,1)(a,1)(b,1)

X<YXY

(?,1)?

  • Xlog2(P)2X
  • P

Xlog2(P)O(n)n

Bây giờ, mỗi "bộ nhớ" cung cấp cho chúng ta bao nhiêu bit thông tin?

  • WW
  • X

P1Xlog2(P)<X

Vì vậy, để lưu trữ tất cả thông tin của chúng tôi, chúng tôi có hai khả năng:

  • Lưu trữ thứ tự chèn trong địa chỉ và tải trọng trong bộ nhớ.
  • Lưu trữ cả trong bộ nhớ và để lại địa chỉ miễn phí cho một số sử dụng khác.

Rõ ràng, để tránh lãng phí, chúng tôi sẽ sử dụng giải pháp đầu tiên.


Bây giờ cho các hoạt động. Tôi cho rằng bạn muốn có:

  • Insert(task,priority)O(logn)
  • StableExtractMin()O(logn)

StableExtractMin()

Thuật toán thực sự thực sự chung như sau:

  1. O(logn)
  2. O(logn)
  3. Trả lại.

0(1)O(1)O(1)

O(logn)2(Xlog2(P))

Xlog2(P)O(logn)O(logn)

O(logn)

O(logn)Xlog2(P)

O(logn)

Xlog2(P)O(logn)

Thuật toán chèn thường chỉ cần cập nhật một phần thông tin này, tôi không nghĩ rằng nó sẽ tốn nhiều tiền hơn (thông minh bộ nhớ) để nó hoạt động nhanh.


Xlog2(P)

  • Xlog2(P)
  • P
  • Xlog2(P)

Ω(n)


bạn đã thực sự có ý định thực hiện câu trả lời của bạn CW?
Suresh Venkat

Vâng. Câu trả lời của tôi không đúng 100%, như đã nêu trong đó, và thật tốt nếu có ai có thể sửa nó ngay cả khi tôi không còn SO nữa hay bất cứ điều gì. Kiến thức nên được chia sẻ, kiến ​​thức nên được thay đổi. Nhưng có lẽ tôi đã hiểu nhầm cách sử dụng CW, nếu vậy, xin vui lòng cho tôi biết :). EDIT: Rất tiếc, tôi thực sự đã phát hiện ra rằng tôi sẽ không nhận được bất kỳ đại diện nào từ các bài đăng của CW và nội dung đó là CC-wiki được cấp phép theo bất kỳ cách nào ... Quá tệ :).
Suzanne Dupéron

3

Nếu bạn triển khai hàng đợi ưu tiên của mình dưới dạng cây nhị phân cân bằng (một lựa chọn phổ biến), thì bạn chỉ cần đảm bảo rằng khi bạn thêm một phần tử vào cây, nó sẽ được chèn vào bên trái của bất kỳ phần tử nào có mức độ ưu tiên như nhau.
Bằng cách này, thứ tự chèn được mã hóa trong cấu trúc của chính cây.


1
Nhưng điều này thêm không gian O (n) cho con trỏ, mà tôi nghĩ là những gì người hỏi muốn tránh?
Jeremy

-1

Tôi không nghĩ điều đó là có thể

trường hợp cụ thể:

       x
    x    x
  x  x  1  x
1  x  

đống tối thiểu với tất cả x> 1

heapifying cuối cùng sẽ cho một cái gì đó lựa chọn như vậy

       x
    1    1
  x  x  x  x
x  x  

Bây giờ cái nào để nhân giống đến root?

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.