Nội dung thuật tốn HeapSort

Một phần của tài liệu Giáo trình cấu trúc dữ liệu và giải thuật (Trang 35 - 37)

• 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 thut 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 ToHeapĐầ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:

Một phần của tài liệu Giáo trình cấu trúc dữ liệu và giải thuật (Trang 35 - 37)

Tải bản đầy đủ (PDF)

(148 trang)