Tải bản đầy đủ (.doc) (15 trang)

Tài liệu Sắp xếp theo kiểu : Heap Sort docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (80.29 KB, 15 trang )

Heap là một cấu trúc dữ liệu , có thể được biểu diễn thông qua 2 cách :
-Dạng thứ 1: Dạng cây nhị phân có đặc điểm là node cha thì lớn hơn 2 node con trực tiếp của nó .
-Dạng thứ 2: nếu ta đánh số các node theo thứ tự từ trên xuống và từ trái qua . Bắt đầu là node root
= 0 , thì ta có thể định nghĩa heap thông qua mảng một chiều , có đặc điểm là phần tử thứ k sẽ lớn
hơn các phần tử thứ 2k+1 và 2k+2 . Ta có thể dễ nhận thấy là phàn tử thứ 0 sẽ tương ứng với root
trong cây ở cách biểu diễn thứ 1
Nguyên tắc sắp xếp của heap sort
Dựa vào tính chất của heap trong cách biểu diễn thứ 1 và thứ 2 , ta có thể thấy phần tử đầu tiên
trong cách biểu diễn theo mảng sẽ là phần tử lớn nhất ---> cách sắp xếp đơn giản là : ( Gọi mảng
ban đầu là A )
Khởi tạo : Tạo heap từ mảng ban đầu đã cho (mảng A )
1. Lấy phần tử đầu tiên trong mảng ra bỏ vào mảng kết quả
2. Tạo lại heap từ mảng A
3.Quay lại bước 1
VD : Ta lấy một mảng đã được tạo thành một heap :
y r p d f b k a c
Lấy phần tử đầu tiên là y bỏ vào mảng kết quả C = { y }
khi này A = r p d f b k a c
Tạo heap A = r f p d c b k a
Lấy phần tử đầu tiên ra là r bỏ vào mảng C = { r y }
Khi này A = { f p d c b k a }
Tạo heap cho A = { p f k d c b a}
Lấy phần tử đầu tiên ra là p bỏ vào mảng C = { p r y }
Khi này A = { f k d c b a }
Tạo heap cho A = { k f b d c a}
Lấy phần tử đầu tiên ra là k bỏ vào mảng C = { k p r y }
Khi này A = { f b d c a }
Tạo heap cho A = { f d b a c}
Lấy phần tử đầu tiên ra là f bỏ vào mảng C = { f k p r y }
Khi này A = { b d c a }
Tạo heap cho A = { d c b a}


Lấy phần tử đầu tiên ra là d bỏ vào mảng C = {d f k p r y }
Khi này A = { c b a }
Tạo heap cho A = { c a b }
Lấy phần tử đầu tiên ra là c bỏ vào mảng C = {c d f k p r y }
Khi này A = { b a }
Tạo heap cho A = { b a }
Lấy phần tử đầu tiên ra là b bỏ vào mảng C = {b c d f k p r y }
Khi này A = { a }
Tạo heap cho A = { a }
Kết thúc ta có được mảng C đã có thứ tự .
Cải tiến:
Ta có thể hạn chế việc sử dụng thêm mảng C bằng cách tận dụng luôn mảng A ban đầu . Ta làm như
sau
A = y r p d f b k a c
Bước 1 :
Lấy y ra
Lấy c ra
Bỏ y vào chổ của c .
Bỏ c vào chỗ của y
Khi ta bỏ y vào chỗ của c thì giống như ta bỏ y vảo mảng C .
Khi này mảng A sẽ coi như gồm 2 phần A = c r p d f b k a ---- y
Bước 2 : tạo heap cho phần đứng trước của A là c r p d f b k a
Phần sau là chứa y để nguyên
Ta sẽ có A mới là : r f p d c b k a -- y
Quay lại bước 1 : Lấy r , a ra và swap r và a
A sẽ thành A= a f p d c b k -- r y
Tạo heap cho A = p f k d c b a -- r y
...........
Làm tương tự đến khi kết thúc
Qua VD ta thấy rằng phần quan trọng nhất là làm sao sinh ra heap từ một mảng cho trước

Sau đây là phần code cho phần cải tiến
Giải thuật
Post Condition : Dùng để phục hồi lại heap .
Pre Condition :
Ta sẽ có A mới là : r f p d c b k a -- y
Quay lại bước 1 : Lấy r , a ra và swap r và a
A sẽ thành A= a f p d c b k -- r y
Tạo heap cho A = p f k d c b a -- r y
Thì khi này current chính là a
low là 0
high là 7
CODE


void Sortable_List::insert_heap(const Record ¤t, int low , int high )
{
int large;
large = 2*low+1;
while ( large <= high ) {
if (large < high && entry[large] < entry[large+1] )
large ++;
if(current >= entry[large] )
{
break;
}
else
{
entry[low] = entry[large];
low = large;
large = 2 * low + 1;

}
}
entry[low] = current;
}
Tạo ra heap lúc ban đầu , lúc chưa chạy giải thuật
void Sortable_List::bulidheap()
{
int low;
for ( low = count / 2- 1; low >= 0; low -- )
{
Record current = entry[low];
insert_heap(current, low, count -1);
}
}
void Sortable_List::heapsort ()
{
Record current;
int last_unsorted;
buildheap();
for ( last_unsorted = count -1; last_unsorted > 0; last_unsorted -- )
{
current = entry[ last_unsorted];
entry[last_unsorted] = entry[0];
insert_heap(current,0,last_unsorted-1);
}
}
mình đã làm xong phần Heap Sort nhưng có 1 chút rắc rối với phần tử đầu tiên a[0], vì nếu áp dụng
công thức các phần tử liên đới thì với i=0 -> 2*i=0 và 2*1+1=1 !!! đáng lẻ ra phải là a[0],a[1],a[2]
mới đúng. Do đó nó kô đụng chạm gì đến a[0] hết. Các bác có cao kiến gì kô :
void heapSort(int a[],int n)

{
int end=n;
MakeHeap(a,n);
while (end > 0)
{ hoanvi(&a[end],&a[1]);
ADHeap(a, 1, end-1);
end--;
}
}
void MakeHeap(int a[],int n)
{
int i=n/2;
for(i;i>0;i--)
ADHeap(a, i, n);
}
void ADHeap(int a[],int i,int n)
{
int j;
while(i*2<=n)
{
j=i*2;
if((j<n)&&(a[j]<a[j+1]))
j++;
if (a[i]<a[j])
{ hoanvi(&a[i],&a[j]);
i=j;
}
else break;
}
}

#include"stdio.h"
#include"conio.h"
void xuatmang(int a[], int n);
void nhapmang(int a[],int &n);
void hoanvi(int *a,int *b);
void createheap(int a[],int n);
void shift(int a[],int l,int r)
{ int x,i,j;
i=l;
x=a[i];
j=2*i;
while(j<=r)
{
if(j<r)
if(a[j]<a[j+1]) //tim phan tu len doi lon nhat://
j=j+1;
if(x<a[j])
{ a[i]=a[j];
i=j; //hieu chinh lan truyen//
j=2*i;
a[i]=x;
}
else
break;
}
}
void createheap(int a[],int n)
{ int l;
l=n/2; //a[l] la phan tu ghep them//
while(l>=0)

{ shift(a,l,n);
l=l-1;
}
}
void hoanvi(int &a,int &b)
{ int temp;
temp=a;
a=b;
b=temp;
}
void nhapmang(int a[],int &n)
{ int i;
printf("/n nhap vao n:");
scanf("%d",&n);
for (i=0;i<n;i++)
{ printf("/n nhap vao %3a[%d]",i);
scanf("%d",&a[i]);
}
}
void xuatmang(int a[], int n)
{
int i;
printf("/n xuat mang");
for(i=0;i<n;i++)
printf("%3d",a[i]);
}
void main()
{ int r,n,a[15];
nhapmang(a,n);printf("%d",a[9]);
xuatmang(a,n);

createheap(a,n);
printf("/n");
xuatmang(a,n);
r=n-1;
while(r>0)
{ hoanvi(a[0],a[r]);
r=r-1;
createheap(a,r);
}
xuatmang(a,n);
getch();
}
******************
#include <stdio.h>
#include <conio.h>
void xuat(int*a,int n)
{
int i;
printf("\n");
for(i=0;i<n;i++)
printf("%3.0d",a[i]);
}
void hoanvi(int*a,int*b)
{

×