• Giai đoạn 1: Từ Heap ban đầu: x[n/2]+1, ..., xn, tạo Heap đầy đủban đầu • Giai đoạn 2: Sắp xếp dãy dựa trên Heap:
- Bước 1: r = n;
- Bước 2: Đưa phần tử lớn nhất về cuối dãy đang xét: Hốn vịx1 và xr
- Bước 3: . Loại phần tử lớn nhất ra khỏi Heap: r = r –1;
. Bổ sung x1 vào heap cũ: x2, ..., xr để được heap mới dài hơn: x1, ..., xr. // dùng thủ tục Shift(x, 1, r)
- Bước 4: if (r > 1) Quay lên bước 2
else Dừng //Heap chỉ cịn một phần tử
* Nội dung thuật tốn Shift: Bổ sung xL vào heap cũ: xL+1, ..., xr để được heap mới dài hơn: xL , ..., xr.
Shift (x, L, R)
- Bước 1: ChỉSốCha = L; ChỉSốCon = 2* ChỉSốCha; Cha = xChỉSốCha; LàHeap = False;
- Bước 2: Trong khi (Chưa LàHeap and ChỉSốCon ≤ R) thực hiện: { if (ChỉSốCon < R) // nếu Cha cĩ con phải, tìm con lớn nhất
if (xChỉSốCon < xChỉSốCon+1) ChỉSốCon = ChỉSốCon +1; if (xChỉSốCon≤ Cha) LàHeap = True;
else { xChỉSốCha = xChỉSốCon; // đưa nút con lớn hơn lên vị trí nút cha
ChỉSốCha = ChỉSốCon; ChỉSốCon = 2* ChỉSốCha;
} }
- Bước 3: xChỉSốCha = Cha;
c. Cài đặt thuật tốn
* Thủ tục Shift:
// Thêm xL vào Heap xL+1, ..., xr để tạo Heap mới dài hơn một phần tử xL, ..., xr,
void Shift(mang x, int L, int R)
{ int ChỉSốCha = L, ChỉSốCon = 2* ChỉSốCha, LàHeap = 0; ElementType Cha = x[ChỉSốCha];
while (!LàHeap && (ChỉSốCon ≤ R))
{ if (ChỉSốCon < R) // Chọn nút cĩ khĩa lớn nhất trong 2 nút con của nút Cha
if (x[ChỉSốCon] < x[ChỉSốCon+1]) ChỉSốCon++; if (Cha >= x[ChỉSốCon]) LàHeap = 1;
else { x[ChỉSốCha] = x[ChỉSốCon]; // Chuyển nút con lớn hơn lên nút cha
ChỉSốCha = ChỉSốCon; ChỉSốCon = 2* ChỉSốCha; } } x[ChỉSốCha] = Cha; return ; }
Chú ý rằng, với dãy ban đầu bất kỳ x1, ..., xn , thì x[n/ 2]+1, ..., xn là Heap ban
đầu (khơng đầy đủ). Sau đĩ áp dụng liên tiếp thuật tốn Shift bổ sung phần tử kề
bên trái vào các Heap đã cĩ, ta được các Heap mới nhiều hơn một phần tử ...
Cuối cùng, ta đựơc Heap đầy đủ ban đầu: x1, ..., xn .
* Tạo Heap đầy đủ ban đầu từ Heap ban đầu của dãy x1, ..., xn
void TạoHeapĐầyĐủ(mang x, int n)
{ int L = n/2, R = n-1; while (L >= 0) Shift(x, L--, R); return ; } * Ví du: Từ dãy 44 55 12 42 94 18 06 67 Heap ban đầu L=3 44 55 12 67 94 18 06 42 L=2 44 55 18 67 94 12 06 42 L=2 44 94 18 67 55 12 06 42 L=1 94 67 18 44 55 12 06 42 Heap đầy đủđã tạo xong * Thủ tục HeapSort
void HeapSort(mang x, int n)
{ TạoHeapĐầyĐủ(x, n);
int L = 0, R = n -1; while (R > 0)
{HốnVị(x[0], x[R]);
} return ; }
Ví dụ: Với Heap ban đầu:
94 67 18 44 55 12 06 42 Ta cĩ biểu diễn cây của dãy sau mỗi bước lặp: