2011-12-29 33 views
5

Tôi có một tham chiếu PriorityQueue chứa một số đối tượng. Khi tôi chèn các phần tử vào hàng đợi ưu tiên, thứ tự được duy trì bởi cấu trúc dữ liệu. Bây giờ sau khi một hoạt động loại bỏ tôi cập nhật một số tài liệu tham khảo đang được tổ chức bởi hàng đợi ưu tiên. Lý tưởng nhất điều này đòi hỏi một hoạt động reheapify trên hàng đợi ưu tiên nhưng như là rõ ràng kể từ khi tôi sửa đổi tài liệu tham khảo được lựa chọn bên ngoài một reheapify không thể được kích hoạt. Vì vậy, cách tốt nhất để đảm bảo rằng tôi có thể có được những lợi thế của một đống như nhanh chóng trích xuất tối đa trong sự hiện diện của sửa đổi các yếu tố tùy ý bên trong hàng đợi là gì? Tôi thấy tôi cần cấu trúc dữ liệu tốt hơn?Khôi phục lại java.util.PriorityQueue sau khi cập nhật các thành phần

Để cụ thể hơn, tôi cần thực hiện một thứ gì đó giống như một đống Fibonacci trong Java. http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm Tính năng này có sẵn không?

+0

Tôi có triển khai một vùng Fibonacci trong Java nếu bạn quan tâm. Nó có sẵn trực tuyến tại http://www.keithschwarz.com/interesting/code/?dir=fibonacci-heap. Hy vọng nó giúp! – templatetypedef

+0

Thậm chí các đống mã định dạng không đàn hồi khi đối mặt với những thay đổi ngoài băng đối với trọng số của các phần tử. Tôi nghĩ rằng bạn cần phải loại bỏ một yếu tố trước khi bạn sửa đổi nó và reinsert nó sau đó. –

+0

loại bỏ một phần tử tùy ý khỏi heap sẽ yêu cầu xây dựng heap O (n) tôi đoán. –

Trả lời

2

Bạn có thể sử dụng cây của riêng mình cho phép các thành phần trùng lặp thay vì đống. Dễ dàng hơn, bạn có thể sử dụng TreeMap<PriorityKey, LinkedHashSet<Value>>. Tất cả các hoạt động này là O (log priorityType):

  • thêm là get(priority).add(value), nếu nhận được trả về null, put(priority, new LinkedHashSet())
  • loại bỏ một yếu tố độc đoán là tương tự, ngoại trừ nhu cầu để loại bỏ các ưu tiên ra khỏi bản đồ nếu Set là trống.
  • cuộc thăm dò() là

-

Entry<PriorityKey, LinkedHashSet<Value>> e = map.firstEntry(); 
if (e==null) return null; 
Iterator<Value> i = e.getValue().iterator(); 
Value v = i.next(); //must always have at least one element. 
i.remove(); 
if (!i.hasNext()) map.remove(e.getKey()); 
return v; 

Tuy nhiên nếu bạn cần thay đổi các ưu tiên bạn phải gỡ bỏ và thêm phần tử.

+0

OK ... vì vậy tôi sẽ nói rằng PriorityQueue trong Java không thực hiện thao tác DecreaseKey cũng không cung cấp một cách để người dùng thực hiện nó một cách hiệu quả. –

+0

@iamrohitbanga, tìm một khóa trong heap là O (n), sau đó bạn có thể loại bỏ/thêm đó là (log N), một lần nữa nếu bạn cần truy cập vào một phần tử ngẫu nhiên trong hàng đợi bạn nên tắt w/a tree . – bestsss

1

Có thể một NavigableMap phù hợp với nhu cầu của bạn: dễ dàng nhận dạng phần tử "cao nhất" hoặc "thấp nhất", chèn nhanh và thời gian truy cập và bạn có thể cập nhật giá trị dễ dàng.

http://docs.oracle.com/javase/7/docs/api/java/util/NavigableMap.html

TreeMap thực hiện NavigableMap, và do đó cung cấp các firstEntry/lastEntry phương pháp, và nhiều hơn nữa.

+0

bạn không thể có các phần tử trùng lặp trong bản đồ và nó phải được sắp xếp theo mức độ ưu tiên. giải pháp sử dụng cây (bản đồ) liên quan đến ánh xạ ưu tiên-> bộ sưu tập.(những gì tôi đã đăng) – bestsss

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