Tại sao trong một hàng đợi ưu tiên tối thiểu (dựa trên heap), nó được gọi là khóa giảm dần và không chỉ là khóa set-key


7

Khi bạn gọi phím giảm trong hàng đợi ưu tiên tối thiểu, về cơ bản bạn đang đặt khóa, bạn có thể vô tình đặt phím cao hơn, phải không? vậy tại sao nó không được gọi là "set-key" hay "update-key"? tại sao (theo Wikipedia và các nguồn khác) hàng đợi ưu tiên tối thiểu có "khóa giảm" và hàng đợi ưu tiên tối đa có "khóa tăng"? tại sao không có cả "set-key" và nếu bạn giảm hoặc tăng nó, hãy làm những gì bạn nên làm để giữ bất động sản heap bất biến?

Ý tôi là nếu tôi gọi phím giảm trên một đống tối thiểu và cho giá trị lớn hơn thì sao? Nó sẽ ném một ngoại lệ? Tại sao không chỉ gọi nó là "set-key" và xử lý bất kỳ loại giá trị nào?

Câu trả lời:


8

Câu hỏi hay. Một trong những ứng dụng quan trọng của cấu trúc dữ liệu PriorityQueue nằm trong thuật toán của Dijkstra. Mỗi nút được một khoảng cách từ nút ban đầu, được cập nhật khi các đường dẫn ngắn hơn được phát hiện. Do đó cập nhật chỉ thay đổi chìa khóa theo một hướng.

Vấn đề trong việc triển khai DecreasKey không phải là nó chỉ giảm (chứ không phải là cập nhật giá trị). Đối với một đống nhị phân, có các phương pháp khá hiệu quả cả tăng và giảm. Cả hai đều trao đổi các nút với các nút khác dọc theo một đường dẫn trong cây (lên hoặc xuống). Vấn đề là thực sự biết nơi để tìm chìa khóa. Bạn không thể tìm kiếm nó một cách hiệu quả, do đó, một "chỉ mục" riêng biệt phải được lưu giữ. Khi một bản cập nhật được thực hiện dọc theo một đường dẫn, không chỉ phím giảm được thay đổi trong indax, mà cả các phím khác dọc theo đường dẫn.

Đối với các cấu trúc dữ liệu trừu tượng chúng tôi muốn chỉ định chỉ hoạt động rất quan trọng trong một bối cảnh cụ thể. Vì vậy, chúng tôi chỉ có DecreasKey, với động lực Dijkstra. Mặc dù đối với các đống nhị phân mở rộng các hoạt động có thể là cơ bản, nhưng điều này có thể không xảy ra đối với các triển khai khác của PriorityQueue, như Heaps Left, Heaps Fibre, hoặc Brodal Heaps.

Bất kỳ việc triển khai cụ thể nào sẽ làm khi giá trị mới sai hướng tùy thuộc vào việc thực hiện đó.


1

Việc đặt tên phương thức có thể có chủ ý trong một số sách giáo khoa (ví dụ CLRS ) vì:

  1. Logic cho "thả xuống" hoặc "sủi bọt" một khóa trong một đống nhị phân rất đơn giản nếu bạn biết bạn đang đi theo hướng nào (lên / xuống). Ví dụ: "sủi bọt" một phím chỉ đơn giản là một cuộc gọi đệ quy trên nút cha mẹ, so với thả xuống nơi bạn cần so sánh với từng đứa trẻ , trước khi tiến hành đệ quy.
  2. Nhiều thuật toán sử dụng heap tối đa / phút yêu cầu bạn chỉ tăng hoặc giảm các khóa, do đó, nó đủ để cung cấp phương thức "thả xuống" hoặc "nổi bọt" tương ứng.

Lưu ý rằng nếu bạn muốn thực hiện một phương pháp "set key" chung, bạn có thể chỉ cần kết hợp hai thói quen này để quyết định hướng đi nào dựa trên việc bạn có cần phải bong bóng lên hay thả xuống phím.

Để thêm vào những gì Hendrick đã nói, đáng chú ý là ngay cả đối với các thuật toán của Dijkstra hay Prim, trong đó về mặt kỹ thuật, thao tác khóa giảm là đủ, sử dụng một đống nhị phân không nhất thiết phải theo dõi vị trí của từng khóa.

Trong các thuật toán này, một khóa đã cho chỉ được trích xuất từ ​​heap một lần . Ví dụ, trong Dijkstra một nút đồ thị chỉ thêm một lần để cây đường đi ngắn nhất, và trong Thuật toán Prim, một cạnh có thể chỉ được thêm một lần để các cây bao trùm nhỏ nhất.

Do đó, thay vì theo dõi các vị trí chủ chốt (hoặc tìm kiếm chúng khi nhu cầu thuật toán để giảm chúng), trên có thể chỉ đơn giản là chèn các mới (trong trường hợp này giảm ) giá trị cho khóa trong đống (dẫn đến các bản sao trong đống) và sau đó, khi bạn trích xuất "khóa" từ heap (dữ liệu vệ tinh về mặt kỹ thuật vì khóa không phải là thứ bạn đang tiêu thụ một cách tham lam), bạn có thể bỏ qua tất cả các lần trích xuất tiếp theo của nó (ví dụ: sử dụng một bộ vớiÔi(1)).

Các bản sao chính và tập hợp như vậy trong heap rõ ràng sẽ khiến bạn phải trả giá Ôi(n)trong độ phức tạp không gian, nhưng bạn có thể nghĩ về giải pháp kết hợp như một phương pháp "khóa giảm" không đòi hỏi kiến thức hoặc theo dõi các vị trí trong heap.

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.