Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 25 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
25
Dung lượng
517,34 KB
Nội dung
Hàng đợi ưu tiên (Priority Queues) Nguyễn Mạnh Hiển hiennm@tlu.edu.vn Hàng đợi ưu tiên • Phần tử nhỏ có độ ưu tiên cao lấy • Chèn (insert) − Thời gian O(log N) • Xóa phần tử nhỏ (deleteMin) − Thời gian O(log N) Cài đặt hàng đợi ưu tiên • Dùng danh sách liên kết: − insert (dùng pushFront) thời gian O(1) − deleteMin (qt tìm xóa min) thời gian O(N) • Dùng nhị phân tìm kiếm: − insert deleteMin thời gian O(log N) − Tuy nhiên, nhị phân tìm kiếm phức tạp cho yêu cầu đơn giản hàng đợi ưu tiên • Đống nhị phân (binary heap): − Là cách cài đặt phổ biến hàng đợi ưu tiên − insert deleteMin thời gian O(log N) Đống nhị phân • Gọi tắt đống • Thỏa mãn: Là nhị phân đầy đủ Có tính chất thứ tự đống Cây nhị phân đầy đủ • Là nhị phân với tất mức (trừ mức cùng) lấp đầy nút từ trái sang phải • Số nút n 20 + 21 + + 2h–1 + = 2h h log n Mức có 20 nút Mức có 21 nút Mức có 22 nút Mức h có nút (h chiều cao cây) Cài đặt nhị phân đầy đủ Lưu trữ phần tử mức vào vector v • Cha v[k] v[k/2] • Con trái v[k] v[2k] • Con phải v[k] v[2k + 1] vector v Tính chất thứ tự đống • Với nút X đống, giá trị X nhỏ giá trị nút trái phải X • Suy ra: − Phần tử nhỏ đống nằm gốc − Khơng có thứ tự nút nút Cây đống? Cài đặt hàng đợi ưu tiên C++ template class BinaryHeap { public: BinaryHeap(int capacity = 100); // Khởi tạo đống rỗng BinaryHeap(const vector & elems); // Dựng đống const T & findMin(); // Tìm phần tử nhỏ (ở gốc) void insert(const T & x); // Chèn x vào đống void deleteMin(); // Xóa phần tử nhỏ (ở gốc) private: int currentSize; // Số phần tử có vector array; // Vector chứa phần tử void buildHeap(); // Giúp dựng đống (trong hàm tạo) void percolateDown(int hole); // Giúp xóa dựng đống }; Chèn vào đống: insert(14) Chèn vào đống: insert(x) • Tạo lỗ trống (hole) vị trí có sẵn đống; x giá trị lỗ trống chưa thức đặt vào lỗ trống • Lặp lại: − Nếu x nhỏ giá trị nút cha lỗ trống: + Đổi chỗ lỗ trống nút cha − Ngược lại: + Dừng lặp • Đặt x vào lỗ trống Quá trình lỗ trống dịch chuyển dần lên gọi thẩm thấu ngược (percolate up) Chèn vào đống: Lập trình void insert(const T & x ) { // Tăng kích thước lần vector đầy if (currentSize == array.size() - 1) array.resize(array.size() * 2); // Thẩm thấu ngược currentSize++; int hole = currentSize; while (hole > && x < array[hole / 2]) { array[hole] = array[hole / 2]; hole = hole / 2; } array[hole] = x; } Xóa khỏi đống: Ví dụ Tạo lỗ trống gốc; Xóa phần tử cuối (x = 31) Xóa khỏi đống: Ví dụ (tiếp) Xóa khỏi đống: Thuật tốn • • • • Tạo lỗ trống nút gốc Gọi x giá trị nút cuối Xóa nút cuối Lặp lại: − Xác định nút nhỏ lỗ trống − Nếu x lớn giá trị nút nhỏ hơn: + Đổi chỗ lỗ trống nút nhỏ (thẩm thấu xuôi – percolate down) − Ngược lại: + Dừng lặp • Đặt x vào lỗ trống Xóa khỏi đống: Lập trình void deleteMin() { array[1] = array[currentSize]; currentSize ; // Thẩm thấu xuôi (xem slide sau) percolateDown(1); } Thẩm thấu xuôi void percolateDown(int hole) { T x = array[hole]; int child; while (hole * array[child]) { array[hole] = array[child]; hole = child; } else break; } array[hole] = x; } Thời gian chạy chèn xóa • Số phép so sánh (số đoạn đứt nét) trình thẩm thấu ngược (chèn) xi (xóa) khơng q chiều cao • Ta biết chiều cao h log n • Suy ra, thời gian chạy thao tác chèn xóa O(log n) Hàm tạo • Xây dựng đống từ tập phần tử có: BinaryHeap(const vector & elems); • Các bước: − Chèn phần tử vào mà không quan tâm tính chất thứ tự đống − Duyệt qua nút từ lên trên, từ phải sang trái: + Tại nút, dùng phép thẩm thấu xi để nút thỏa mãn tính chất thứ tự đống • Thời gian chạy O(n) (sẽ phân tích sau) Hàm tạo: Lập trình BinaryHeap(const vector & elems) { array.resize(elems.size() + 10); currentSize = elems.size(); for (int i = 0; i < elems.size(); i++) // O(n) array[i + 1] = elems[i]; buildHead(); // O(n), phân tích sau } // Thiết lập tính chất thứ tự đống void buildHead() { for (int i = currentSize / 2; i > 0; i ) percolateDown(i); } Hàm tạo: Ví dụ percolateDown(7) percolateDown(6) percolateDown(5) Hàm tạo: Ví dụ (tiếp) percolateDown(4) percolateDown(3) percolateDown(2) percolateDown(1) Thời gian chạy buildHeap • Thời gian chạy buildHead tỉ lệ với tổng số đoạn đứt nét tổng chiều cao S tất nút tổng chiều cao S2 tất nút nhị phân hoàn hảo tương ứng (mức lấp đầy) • Cộng chiều cao nút theo mức cây: 𝑆2 = ℎ + ℎ − + 22 ℎ − + ⋯ + 2ℎ−1 • Nhân hai vế với 2: 2𝑆2 = 2ℎ + 22 ℎ − + 23 ℎ − + ⋯ + 2ℎ • Trừ hai đẳng thức theo vế: ℎ − 𝑆2 = −ℎ + + 22 + 23 + ⋯ + 2ℎ−1 + 2ℎ = −ℎ + × 1−2 ℎ ℎ =2×2 2