Sắp xếp vun đống - Heap sort • Khi tìm phần tử nhỏ nhất ở bước i, phương pháp sắp xếp chọn trực tiếp không tận dụng được các thông tin đã có được do các phép so sánh ở bước i-1. Vì lý do trên người ta tìm cách xây dựng một thuật toán sắp xếp có thể khắc phục nhược điểm này.
Trang 1Sắp xếp vun đống
Heap sort
Trang 2Sắp xếp vun đống - Heap sort
các thông tin đã có được do các phép so sánh ở bước i-1 Vì lý do trên người ta tìm cách xây dựng một thuật toán sắp xếp có thể khắc phục nhược điểm này.
các thông tin về sự so sánh giá trị các phần tử trong qua trình sắp xếp
sau :
Trang 3Các phần tử tốt nhất (xấu nhất) sẽ được dời lên trên
Trang 4Cấu trúc heap
• Heap là một cấu trúc dữ liệu dạng hình cây có tính chất sau:
• Mổi một phần tử sẽ có nhiều nhất 2 phần tử là con của nó (phần tử liên đới)
• Bất kỳ Phần tử ở trên (cha) sẽ có giá trị lớn hơn giá trị 2 phần tử con của nó
• Phần tử đầu (phần tử gốc) sẽ là phần tử có giá trị lớn nhất trong heap
Trang 6• Heap có các tính chất sau :
• Tính chất 1 : Nếu al , al+1 ,al+2 , ar là một heap thì khi cắt bỏ một số phần tử ở
hai đầu của heap, dãy con còn lại vẫn là một heap
• Tính chất 2 : Nếu a1 , a2 , , an là một heap thì phần tử a1 (đầu heap) luôn là
phần tử lớn nhất trong heap
• Tính chất 3 : Mọi dãy al , al+1 ,al+2 , ar với 2l > r là một heap.
Trang 7(a2i+1, a2i+2) là các cặp phần tử liên đới
• phần tử a0 (đầu heap) luôn là phần tử lớn nhất trong heap
• Vậy ak có phần tử liên đới là a2k+1, a2k+2
• Phần tử cha của nó la a(k-1)/2
Trang 816 12 14 11 4 9 13 7 6 2 1 0 8 3 10 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
Trang 10Cấu trúc heap
• Thêm 1 phần tử
– Thêm vào cuối mảng
mất tính chất heap
Cập nhật lại heap (upheap)
Bước 1:tại k kiểm tra so với cha của nó (k1-1)/2 Nếu ak <=a(k-1)/2 không thay đổi dừng
Nếu ak >a(k-1)/2 đổi vị trí bước 1
Trang 16Cấu trúc heap (C)
• Thuật toán upheap
• Void uphead(int a[], int N){
• Int k=N-1;
• While (k>0)&&(a[k]>a[(k)/2]) {hoanvi(a[k],a[k/2]);k=k/2;}
• }
Trang 18Cấu trúc heap
• Xóa phần tử
• Thông thường cấu trúc heap thường lấy phần tử gốc (đầu) ra khỏi heap
mất tính chất heap cập nhật heap
Trang 19Cấu trúc heap
• Cách giải quyết 1:
• Chọn trong 2 phần tử liên đới phần tử nào lớn hơn thì đưa lên
mảng bị phân mảnh, trống
Trang 2211 4
13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
Trang 2313
5
10 3
11 4
3 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0
Trang 25Cấu trúc heap
• Cách giải quyết 2:
• Đưa phần tử cuối lên thay thế
• Bước 1 :Chọn phần tử lớn nhất trong phần tử đang xét và 2 phần tử liên đới đưa lên
Trang 2913
10 3
Trang 32Downheap (tt)
• vtconmax = j;//phan tu lon nhat la j // khi khong du hay du 2 phan tu lien doi
• if (j < r)
• { // neu co du 2 phan tu lien doi
• if (tappt[j] < tappt[j + 1]) vtconmax +=1;// giu vi tri con max la j+1
Trang 33• Nếu lấy phần tử lớp nhất ra khỏi heap thì phần tử gốc của heap mới vẫn là phần tử lớn nhất của phần dữ liệu còn lại (do heap tự cập nhật)
• Lấy tuần tự mảng sắp xếp
Trang 34• Giải thuật Heapsort trải qua 2 giai đoạn :
• Giai đoạn 1 :Hiệu chỉnh dãy số ban đầu thành heap;
• Giai đoạn 2: Sắp xếp dãy số dựa trên heap:
– Bước 1:Ðưa phần tử lớn nhất về vị trí đúng ở cuối dãy:
r = n; Hoánvị (a0 , ar );
– Bước 2:Loại bỏ phần tử lớn nhất ra khỏi heap: r = r-1; Hiệu chỉnh phần còn lại của dãy từ a0 , a1 ar thành một heap (downheap)
– Bước 3:Nếu r>0 (heap còn phần tử ): Lặp lại Bước 2 Ngược lại : Dừng
Trang 35an/2+2 an, lần lượt thêm vào các phần tử an/2, an/2-1, , a1 ta sẽ nhân được heap theo mong muốn Như vậy, giai đoạn 1 tương đương với n/2 lần thực hiện bước 2 của giai đoạn 2.
• Ví dụ : sắp xếp mảng :
2 12 9 5 4 14 3 7 6 16 1 0 8 13 10 11
Trang 50Heapsort- hiểu chỉnh heap
• Thủ tục hiệu chỉnh dãy al , al+1 ar thành heap
void Shift (int a[ ], int l, int r )
• Hiệu chỉnh dãy a0 , a1 aN-1 thành heap:
void CreateHeap(int a[], int N-1 )
Trang 51Giả sử có dãy al , al+1 ar, trong đó đoạn al+1 ar, đã là một heap Ta cần xây dựng hàm hiệu chỉnh al , al+1 ar thành heap Ðể làm điều này, ta lần lượt xét quan hệ của một phần tử ai nào đó với các phần tử liên đới của nó trong dãy là a2i+1 và
a2i+2, nếu vi phạm điều kiện quan hệ của heap, thì đổi chỗ ai với phần tử liên đới
thích hợp của nó Lưu ý việc đổi chỗ này có thể gây phản ứng dây chuyền:
Trang 52• if (j<r) // nếu có đủ 2 phần tử liên đới
if (a[j]<a[j+1])// xác định phần tử liên đới lớn nhất
j = j+1;
if (a[j]<x)exit();// thoả quan hệ liên đới, dừng.
else { a[i] = a[j];
i = j;// xét tiếp khả năng hiệu chỉnh lan truyền
Trang 53• { // neu co du 2 phan tu lien doi
• if (tappt[j] < tappt[j + 1]) vtconmax +=1;// giu vi tri con max la j+1
Trang 54Cho một dãy bất kỳ a0 , a1, , ar , theo tính chất 3, ta có dãy an/2+1 , an/2+2 an đã
là một heap Ghép thêm phần tử an/2 vào bên trái heap hiện hành và hiệu chỉnh lại dãy an/2 , an/2+1, , ar thành heap
Trang 55• void CreateHeap(int a[], int N )
{ int l;
l = N/2; // a[l] là phần tử ghép thêmwhile (l > 0) do
{
Shift(a,l,N);
l = l -1;
}}
Trang 65Heapsort (c)
r = N-1; // r là vị trí đúng cho phần tử nhỏ nhất while(r >= 0) do
Trang 67• Ðánh giá giải thuật
• Việc đánh giá giải thuật Heapsort rất phức tạp, nhưng đã chứng minh được trong trường hợp xấu nhất độ phức tạp O(Nlog2N)