ShellSort 2/8 Phương pháp sắp xếp ShellSort còn được gọi là phương pháp sắp xếp giảm độ tăng - diminishing increment sort.. N ếu n là kích thươc của mảng cần sắp xếp, mỗi lần sắp c
Trang 1Gi ảng viên: TS Ngo Huu Phuc
Tel: 0438 326 077 Mob: 098 5696 580
Bài 7 Các phương pháp sắp xếp khác
Trang 37.1 ShellSort (1/8)
năm 1959.
toán so sánh, nhưng sử dụng nhiều phép di
sánh.
Trang 47.1 ShellSort (2/8)
Phương pháp sắp xếp ShellSort còn được gọi là
phương pháp sắp xếp giảm độ tăng - diminishing
increment sort.
Phương pháp sử dụng một dãy tăng: h 1 , h 2 , h t
Dãy t ăng được bắt đầu từ 1, tối đa đến N-1 (trong thực
t ế đến N/2) Chưa có đề xuất dãy như thế nào tốt nhất.
Trong dãy này, không nên ch ọn các số là bội của nhau.
Dãy này còn được gọi là dãy khoảng cách, ví dụ 1,3,5.
Trang 67.1 ShellSort (4/8)
#include <stdio.h>
#include <conio.h>
#define MAX 100
void inputdata(int* list,int n);
void printlist(int* list,int n);
void shellsort(int*list, int n, int *incs, int t);
Trang 7}list[j]=temp;
Trang 87.1 ShellSort (6/8)
Trang 97.1 ShellSort (7/8)
đó có 2 dạng:
Trang 117.2 Mergesort (1/9)
Ý t ưởng:
Trang 127.2 Mergesort (2/9)
Các bước thực hiện:
B ắt đầu từ một mảng có 1 ph ần tử, nối với mảng thứ hai cũng
có 1 ph ần tử để tạo thành mảng mới có 2 phần tử.
M ột cách tương tự, ta nối mảng ba và mảng bốn để được
m ảng mới có 2 phần tử, tiếp tục như trên cho đến khi hết, như
v ậy ta đã thực hiện xong m ột lần sắp xếp (one pass).
Ti ếp theo, nối hai mảng có kích thước 2 ph ần tử lại để được
m ột mảng có kích thước 4 ph ần tử Đến khi kết thúc, ta đã qua
l ần sắp xếp thứ hai.
Ti ếp tục quá trình trên cho đến khi chỉ còn 1 mảng, khi đó mảng
đã được sắp xếp!!!
Trang 137.2 Mergesort (3/9)
Trang 15void readlist(intlist[],intn);
void printlist(intlist[],intn);
void merge(int list[],intlisttemp[],int k,int m,int n);
void mpass(intlist[],intlisttemp[],intl,int n);
void mergesort(intlist[], int n );
Trang 16// Noi 2 mang da sap xep
// Mang thu nhat: tu phan tu thu k den phan tu thu m
// Mang thu nhat: tu phan tu thu m+1 den phan tu
if(list[i] <= list[j]){
listtemp[k] = list[i];i++;
k++;
}
else
{listtemp[k] = list[j];j++;
k++;
}}
Trang 17i = i + 2*l; }
if((i+l-1) < n)merge(list,listtemp,i,(i+l-1),n);
else
while (i <= n ) {listtemp[i] = list[i];
i++;
Trang 197.2 Mergesort (9/9)
Phân tích độ phức tạp của thuật toán MergeSort:
Trong trường hợp tồi nhất: O(N log N)
Trong trường hợp tốt nhất: O(N log N)
Trong trường hợp trung bình: O(N log N)
Vì sao?
N ếu n là kích thươc của mảng cần sắp xếp, mỗi lần sắp
các nhóm con, độ phức tạp sẽ là O(n), hơn nữa số lần lặp
l ại quá trình sắp trên là log2n.
Cho t ất cả các trường hợp, độ phức tạp của Merge Sort là
O(n log 2 (n)), tuy nhiên c ần sử dụng thêm một mảng có
Trang 207.3 Bucket sort (1/6)
Gi ả sử các giá trị cần sắp nằm trong khoảng: 0 m
Thu ật toán Bucket Sort th ực hiện:
Kh ởi tạo m chiếc thùng ( buckets ) được đánh số: 0 … m.
Ki ểm tra từng phần tử S[i] trong danh sách S và đưa vào thùng th ứ i
Như vậy, ta có m thùng với các giá trị đã được đưa vào theo đúng trật tự.
Sau đó, sắp lại các phần tử theo từng thùng, dựa trên chỉ số
c ủa thùng.
Phương pháp này không cần phép toán so sánh.
Trang 217.3 Bucket sort (2/6)
0 0 0
1 1
2
2 2 2
3 3
4 4
Trang 227.3 Bucket sort (3/6)
#include <stdio.h>
#include <conio.h>
#define MAX 100
int inputdata(int* list,intn);
void printlist(int* list,int n);
void bucketsort(int*list, int n, int m);
Trang 23list[i] = j;
Trang 247.3 Bucket sort (5/6)
Đánh giá độ phức tạp của phương pháp:
Để khởi tạo m thùng, thời gian cần thiết: O(m)
Để đưa các phần tử từ danh sách vào thùng, thời gian
c ần thiết: O(n)
Để đưa các phần tử từ các thùng vào danh sách cần: O(n)
Lưu ý: mặc dù, trong đoạn này vẫn có 2 vòng lặp lồng nhau, tuy nhiên, s ố phần tử được xét vẫn chỉ là n ph ần tử.
N ếu như m nhỏ hơn n (thông thường), độ phức tạp của Bucket Sort là O(n)
T ổng quát hóa, độ phức tạp của phương pháp là: O(n+m)
Trang 257.3 Bucket sort (6/6)
M ột số vấn đề của Bucket Sort:
Có th ể áp dụng thuật toán cho các dãy chỉ có các số
nguyên dương không?
Có th ể áp dụng, tuy nhiên số thùng sẽ phụ thuộc vào giá
tr ị lớn nhất của dãy số đó.
N ếu cần sắp 1000 số nguyên dương, giá trị lớn nhất là
999 999, khi đó cần 1 triệu thùng.
Như vậy, với n<<m, độ phức tạp của thuật toán là O(m)
Có th ể có cách khác giải quyết vấn đề này được không?
Thu ật toán sẽ được giới thiệu ở phần sau
Trang 267.4 Radix sort (1/6)
Ý t ưởng : l ặp lại nhiều lần phương pháp sắp theo
Bucket d ựa trên biểu diễn của số.
N ếu giá trị lớn nhất là 999999, chỉ cần tối đa 10
bucket (thay cho 1 tri ệu bucket của phương pháp
Bucket Sort)
Phương pháp Radix Sort được sử dụng khi khóa
trong quá trình s ắp xếp là số nguyên và có giới hạn.
S ố lần gọi Bucket Sort (Number of passes) phụ thuộc vào bi ểu diễn của phần tử lớn nhất.
Trang 2758 18 88
9 99
Trang 28Example: Second pass
Trang 297.4 Radix sort (4/6)
N ếu cố định p lần dùng Bucket Sort ( p = 6 nếu giá trị
l ớn nhất không quá 999 999), độ phức tạp của Radix Sort là O(n)
V ới mỗi lần dùng Bucket Sort, độ phức tạp là O(n).
N ếu kể thêm thông tin về p, độ phức tạp thực sự là
O(pn), v ới p là số chữ số trong biểu diễn của số lớn
nh ất.
Chú ý, p = log 10 m, v ới m là số lớn nhất trong danh
Trang 307.4 Radix sort (5/6)
Radix Sort ho ạt động cứng, theo thứ tự trong mỗi lần dùng Bucket Sort.
Ho ạt động cứng được hiểu theo nghĩa có thứ tự nhất định (từ
ph ải qua trái đối với biểu diễn số của các phần tử trong danh sách)
Ví d ụ, 2 số có biểu diễn số đầu tiên giống nhau:
52 và 58
S ố 52 xuất hiện trước số 58 trong danh sách, số 52 sẽ có trong danh sách k ết quả trước số 58.
Trang 317.4 Radix sort (6/6)
Chú ý: ch ỉ cần 10 bucket cho mỗi lần gọi Bucket Sort.
Radix Sort có th ể sử dụng cho chữ cái không? Có
th ể được bằng cách:
M ỗi từ có số chữ cái có giới hạn.
S ử dụng 27 bucket (có thể thêm nếu có những ký
t ự lạ) cho mỗi chữ cái và 01 bucket cho ký tự
“Space bar”.
Th ực hiện tương tự như đối với biểu diễn số, bằng