Priority Queue

2
HÀNG ðỢI ƯU TIÊN Gii thiu Hàng ñợi ưu tiên (Priority Queue – PQ) là cấu trúc dữ liệu (trừu tượng) cho phép lưu trữ các phần tử cùng với ñộ ưu tiên của nó và khi lấy phần tử ra khỏi hàng ñợi sẽ căn cứ vào ñộ ưu tiên của chúng. Thường thì ñộ ưu tiên là một số nguyên và chúng ta qui ước phần tử có ñộ ưu tiên thấp hơn là phần tử ưu tiên hơn. Hàng ñợi ưu tiên thường lấy phần tử ưu tiên nhất. Các thao tác cơ bản trên hàng ñợi ưu tiên: - Khởi tạo: Init(PQ). Thao tác này khởi tạo hàng ñợi ưu tiên PQ. Nghĩa là làm cho PQ rỗng và sẵn sàng tiếp nhận phần tử. - Kiểm tra rỗng: IsEmpty(PQ). Thao tác này trả về giá trị TRUE nếu PQ rỗng; ngược lại trả về giá trị FALSE. PQ rỗng khi và chỉ khi nó không chứa phần tử nào cả. - Thêm phần tử cùng với ñộ ưu tiên của nó: Insert(PQ, element, priority). Thao tác này thêm phần tử element với ñộ ưu tiên priority vào hàng ñợi. Thật ra thao tác này là thao tác “thêm mới hoặc cập nhật nếu cần” vì lí do: o Nếu element chưa có trong PQ thì element với ñộ ưu tiên priority ñược thêm vào PQ. o Nếu element ñã có trong PQ với ñộ ưu tiên là oldpriority priority lại thấp hơn oldpriority thì sửa ñộ ưu tiên của element thành priority. o Nếu element ñã có trong PQ với ñộ ưu tiên là oldpriority priority lại không thấp hơn oldpriority thì vẫn giữ ñộ ưu tiên của element là oldpriority. - Lấy phần tử ưu tiên nhất: PopLeast(PQ). Trả về phần tử ưu tiên nhất cùng với ñộ ưu tiên của nó ñồng thời gỡ nó khỏi PQ. Nếu có hơn một phần tử ưu tiên nhất thì trả về một trong số chúng. Thao tác này “không hợp lệ” nếu PQ rỗng. Do ñó cần kiểm tra PQ rỗng hay không trước khi dùng thao tác này. - Hủy: Dispose(PQ). Thao tác hủy làm cho PQ rỗng và giải phóng các tài nguyên mà PQ chiếm giữ. Ví dụ : Với PQ là một hàng ñợi ưu tiên. Kí hiệu (e, p) cho phần tử e cùng với ñộ ưu tiên p của nó. Thao tác Trả về Các phần tử của PQ Init(PQ) {} IsEmpty(PQ) TRUE {} Insert(PQ, a, 2) {(a, 2)}

Transcript of Priority Queue

HÀNG ðỢI ƯU TIÊN

Giới thiệu

Hàng ñợi ưu tiên (Priority Queue – PQ) là cấu trúc dữ liệu (trừu tượng) cho phép lưu trữ các phần tử cùng với ñộ ưu tiên của nó và khi lấy phần tử ra khỏi hàng ñợi sẽ căn cứ vào ñộ ưu tiên của chúng. Thường thì ñộ ưu tiên là một số nguyên và chúng ta qui ước phần tử có ñộ ưu tiên thấp hơn là phần tử ưu tiên hơn. Hàng ñợi ưu tiên thường lấy phần tử ưu tiên nhất.

Các thao tác cơ bản trên hàng ñợi ưu tiên:

- Khởi tạo: Init(PQ). Thao tác này khởi tạo hàng ñợi ưu tiên PQ. Nghĩa là làm cho PQ rỗng và sẵn sàng tiếp nhận phần tử.

- Kiểm tra rỗng: IsEmpty(PQ). Thao tác này trả về giá trị TRUE nếu PQ rỗng; ngược lại trả về giá trị FALSE. PQ rỗng khi và chỉ khi nó không chứa phần tử nào cả.

- Thêm phần tử cùng với ñộ ưu tiên của nó: Insert(PQ, element, priority). Thao tác này thêm phần tử element với ñộ ưu tiên priority vào hàng ñợi. Thật ra thao tác này là thao tác “thêm mới hoặc cập nhật nếu cần” vì lí do:

o Nếu element chưa có trong PQ thì element với ñộ ưu tiên priority ñược thêm vào PQ.

o Nếu element ñã có trong PQ với ñộ ưu tiên là oldpriority mà priority lại thấp hơn oldpriority thì sửa ñộ ưu tiên của element thành priority.

o Nếu element ñã có trong PQ với ñộ ưu tiên là oldpriority mà priority lại không thấp hơn oldpriority thì vẫn giữ ñộ ưu tiên của element là oldpriority.

- Lấy phần tử ưu tiên nhất: PopLeast(PQ). Trả về phần tử ưu tiên nhất cùng với ñộ ưu tiên của nó ñồng thời gỡ nó khỏi PQ. Nếu có hơn một phần tử ưu tiên nhất thì trả về một trong số chúng. Thao tác này “không hợp lệ” nếu PQ rỗng. Do ñó cần kiểm tra PQ có rỗng hay không trước khi dùng thao tác này.

- Hủy: Dispose(PQ). Thao tác hủy làm cho PQ rỗng và giải phóng các tài nguyên mà PQ chiếm giữ.

Ví dụ: Với PQ là một hàng ñợi ưu tiên. Kí hiệu (e, p) cho phần tử e cùng với ñộ ưu tiên p của nó.

Thao tác Trả về Các phần tử của PQ Init(PQ) {} IsEmpty(PQ) TRUE {} Insert(PQ, a, 2) {(a, 2)}

Insert(PQ, a, 1) {(a, 1)} Insert(PQ, b, 3) {(a, 1), (b, 3)} Insert(PQ, a, 4) {(a, 1), (b, 3)} PopLeast(PQ) (a, 1) {(b, 3)} IsEmpty(PQ) FALSE {(b, 3)} Dispose(PQ) {}

Cài đặt

Hàng ñợi ưu tiên thường ñược cài ñặt hiệu quả bằng cấu trúc dữ liệu Heap: cả hai thao tác thêm và lấy ñều có ñộ phức tạp là O(logn). Sinh viên tham khảo các giáo trình về Cấu trúc dữ liệu ñể biết cách cài ñặt Heap (Chẳng hạn, Giáo trình Cấu trúc dữ liệu và Thuật toán của Thầy Dương Anh ðức – cuốn trắng trắng!).

Một cách cài ñặt khác là dùng Danh sách liên kết có thứ tự. Khi ñó thao tác thêm có ñộ phức tạp O(n) nhưng thao tác lấy có ñộ phức tạp là O(1). Ví dụ về một số hàng ñợi ưu tiên và danh sách liên kết có thứ tự tương ứng:

Hàng ñợi ưu tiên Danh sách liên kết có thứ tự {}

{(a, 1)}

{(b, 2), (a, 1)}

{(b, 2), (c, 3), (a, 1)}

{(b, 2), (d, 1), (c, 3), (a, 1)}

Danh sách liên kết có thứ tự cài ñặt hàng ñợi ưu tiên là danh sách liên kết có sắp xếp theo thứ tự ñộ ưu tiên tăng dần.

Sinh viên dùng kiến thức ñã học về danh sách liên kết, dưới sự hướng dẫn của GVHDTH hãy cài ñặt hàng ñợi ưu tiên bằng danh sách liên kết có thứ tự.

(a, 1) (b, 2)

(a, 1)

(a, 1) (b, 2) (c, 3)

(a, 1) (d, 1) (b, 2) (c, 3)