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

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

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

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) { int tam; tam=*a; *a=*b; *b=tam; } void heapsort(int*a,int n) { int i,j,tam; i=n/2; while(i>=0) { if(a[i]<a[2*i]) hoanvi(&a[i],&a[2*i]); if(a[i]<a[2*i+1]&&2*i+1<=n) hoanvi(&a[i],&a[2*i+1]); if(a[2*i]<a[4*i]&&4*i<=n) hoanvi(&a[2*i],&a[4*i]); if(a[2*i]<a[4*i+1]&&4*i+1<=n) hoanvi(&a[2*i],&a[4*i+1]); i--; } xuat(a,10); tam=a[0]; for(j=0;j<n;j++) a[j]=a[j+1]; a[j]=tam; xuat(a,10); } main() { int a[10]={5,1,2,6,9,10,4,12,7,3},n=10; xuat(a,n); for(n=9;n>0;n--) heapsort(a,n); getch(); } 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 void Sortable_List<Record>::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<Record>::bulidheap() { int low ; for ( low = count / 2- 1; low >= 0 ; low -- ) { Record current = entry[low] ; insert_heap(current, low, count -1) ; } } void Sortable_List<Record>::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) ; } } [...]... kt; while (mid>=0) { Adjust(mid,n,a); mid; } } void Heap_ sort( int n,int *a) { int right=n-1; int tam; int dem=0; puts("Cac buoc chay cua chuong trinh: "); Create _heap( n-1,a); while (right>0) { Hoanvi(a[0],a[right],tam); ++dem; right; printf("Buoc %d:",dem); Output(n,a); Adjust(0,right,a); } } void main() { int n; int a[maxn]={0}; Input(&n,a); Heap_ sort( n,a); getch(); } #include #include ... {c=a;a=b;b=c;} #define fi "Heap_ sort. inp" FILE *f; void Input(int *n,int *a) { //Tu nhap theo y minh } void Output(int n,int *a) { for (int i=0;i . entry[low]; insert _heap( current, low, count -1); } } void Sortable_List::heapsort () { Record current; int last_unsorted; buildheap(); for ( last_unsorted = count. insert _heap( current, low, count -1) ; } } void Sortable_List<Record> ;:: heapsort () { Record current ; int last_unsorted ; buildheap() ; for ( last_unsorted

Ngày đăng: 12/12/2013, 20:15

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan