Giải thuật Heap Sort

Một phần của tài liệu Kỹ thuật lập trình (Trang 142 - 144)

Heap là một cây nhị phân được biểu diễn bằng một mảng, mảng đó biểu diễn một cây nhị phân hoàn chỉnh sao cho khóa ở node cha bao giờ cũng lớn hơn khoá của node con của nó.

Sắp xếp kiểu Heap Sort được tiến hành qua hai giai đoạn. Giai đoạn đầu tiên cây nhị

phân biểu diễn bảng khoá được biến đổi đểđưa về một heap. Như vậy, đối với heap, nếu j

là chỉ số của node con thì [j/2] là chỉ số của node cha. Theo định nghĩa của heap thì node con bao giờ cũng nhỏ hơn node cha. Như vậy, node gốc của heap là khóa có giá trị lớn nhất trong mọi node. Ví dụ cây ban đầu là cây 6.1a thì heap của nó là 6.1b.

Hình 6.1a Hình 6.1b

Để chuyển cây nhị phân 6.1a thành cây nhị phân 6.1b là một heap, chúng ta thực hiện duyệt từ dưới lên (bottom up). Node lá đương nhiên là một heap. Nếu cây con bên trái và cây con bên phải đều là một heap thì toàn bộ cây cũng là một heap. Như vậy, để tạo thành heap, chúng ta thực hiện so sánh nội dung node bên trái, nội dung node bên phải với node cha của nó, node nào có giá trị lớn hơn sẽđược thay đổi làm nội dung của node cha. Quá trình lần ngược lại cho tới khi gặp node gốc, khi đó nội dung node gốc chính là khoá có giá trị lớn nhất.

Giai đoạn thứ hai của giải thuật là đưa nội dung của node gốc về vị trí cuối cùng và nội dung của node cuối cùng được thay vào vị trí node gốc, sau đó coi như node cuối cùng nhưđã bị loại bỏ vì thực tế node cuối cùng là giá trị lớn nhất trong dãy số.

87 42 23 74 11 65 58 94 36 99 99 87 94 36 58 65 74 23 42 11

Cây mới được tạo ra (không kể phần tử loại bỏ) không phải là một heap, chúng ta lại thực hiện vun thành đống và thực hiện tương tự như trên cho tới khi đống còn một phần tử

là phần tử bé nhất của dãy.

Độ phức tạp thuật toán của Heap Sort

Cmax = Ctb = O (n log2n )

Giải thuật Heap Sort được cài đặt như sau:

#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <alloc.h> #include <dos.h> void Heap(int *, int ); void Init(int *, int); void In(int *, int); void Init(int *A, int n){

int i;

printf("\n Tao lap day so:"); for (i=0; i<n;i++){

A[i]=random(1000); printf("%5d",A[i]); }

delay(1000); }

void Heap(int *A, int n) { int k,x,s,f,ivalue; for(k=1;k<n;k++){

x=A[k];

s=k; f=(s-1)/2; while(s>0 && A[f]<x){ A[s]=A[f]; s=f; f=(s-1)/2; } A[s]=x; } for(k=n-1;k>0;k--){ ivalue=A[k]; A[k]=A[0]; f=0; if(k==1) s=-1;

else s=1;

if(k>2 && A[2]>A[1]) s=2;

while(s>=0 && ivalue<A[s]){ A[f]=A[s]; f=s;s=2*f +1; if (s+1<=k-1 && A[s]<A[s+1]) s=s+1; if (s>k-1) s=-1; } A[f]=ivalue; } }

void In(int *A, int n){ register int i; for(i=0;i<n;i++) printf("%5d",A[i]); delay(1000); } void main(void){ int *A,n;clrscr();

printf("\n Nhap n="); scanf("%d",&n); A=(int *) malloc(n*sizeof(int)); Init(A,n);Heap(A,n);printf("\n"); In(A,n);getch();

free(A); }

Một phần của tài liệu Kỹ thuật lập trình (Trang 142 - 144)

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

(156 trang)