Tải bản đầy đủ (.pdf) (31 trang)

Bài giảng Cấu trúc dữ liệu và giải thuật – Bài 7: Các phương pháp sắp xếp khác

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 (768.45 KB, 31 trang )

Cấu trúc dữ liệu và giải thuật
Bài 7. Các phương pháp sắp xếp khác
Giảng viên: TS. Ngo Huu Phuc
Tel:
0438 326 077
Mob: 098 5696 580
Email:

1

Ngo Huu Phuc, Le Quy Don Technical University


Bài 7. Các phương pháp sắp xếp khác
Nội dung:
7.1. ShellSort (8)
7.2. MergeSort (9)
7.3. BucketSort (5)
7.4. RadixSort (6)
Tham khảo:
1.
2.
3.
4.
5.
2

Bucket sort.htm
Merge Sort.htm
Radix sort.htm
ShellSort.htm


Bài giảng của TS Nguyên Nam Hồng
Ngo Huu Phuc, Le Quy Don Technical University


7.1. ShellSort (1/8)
 Phương pháp này được Donald Shell giới thiệu

năm 1959.
 Với phương pháp sắp xếp chèn: thực hiện ít phép

toán so sánh, nhưng sử dụng nhiều phép di
chuyển thừa.
 Với phương pháp sắp xếp chọn: thực hiện ít phép

toán di chuyển, nhưng sử dụng nhiều phép so
sánh.
 Có thể có phương pháp hiệu quả hơn không?
3

Ngo Huu Phuc, Le Quy Don Technical University


7.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: h1, h2, .. ht
 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.

4

Ngo Huu Phuc, Le Quy Don Technical University


7.1. ShellSort (3/8)
 Ví dụ: với 13 phần tử, dãy khoảng cách là 1,3,5

5

STT

0

1

2

3

4

5

6


7

8

9

10

11

12

Ban
đầu

81

94

11

96

12

35

17

95


28

58

41

75

15

KC
=5

35

17

11

28

12

41

75

15


96

58

81

94

95

KC
=3

28

12

11

35

15

41

58

17

94


75

81

96

95

KC
=1

11

12

15

17

28

35

41

58

75


81

94

95

96

Ngo Huu Phuc, Le Quy Don Technical University


7.1. ShellSort (4/8)
#include <stdio.h>

for(int i=0;i
#include <conio.h>

scanf("%d",&incs[i]);

#define MAX 100

shellsort(list,n,incs,t);

void inputdata(int* list,int n);

printf("Mang da sap xep:\n");

void printlist(int* list,int n);


printlist(list,n);

void shellsort(int *list, int n, int *incs, int t);

getch();

void main() {
int list[MAX], n;

}

int incs[MAX], t;

void inputdata(int* list,int n)

printf("Nhap so phan tu cua mang:\n");

{

scanf("%d",&n);

int i;

inputdata(list,n);

printf("Nhap cac phan tu cua mang\n");

printf("Mang da nhap:\n");

for(i=0;i


printlist(list,n);

scanf("%d",&list[i]);

printf("Nhap so phan tu cua mang khoang cach:");
scanf("%d",&t);
printf("Nhap gia tri cua mang khoang cach:");

6

Ngo Huu Phuc, Le Quy Don Technical University

fflush(stdin);
}


7.1. ShellSort (5/8)
void printlist(int* list,int n)

void shellsort(int *list, int n, int *incs, int t)

{

{
int i;

int i,j,k,h;

printf("Cac phan tu cua mang: \n");


int temp;

for(i=0;i
for(k=t-1; k>0; k--)

printf("%d\t",list[i]);

for(h=incs[k], i=h; i
printf("\n");

temp=list[i];

}

j=i;
while(j>=h && list[j-h]>temp)
{
list[j]=list[j-h];
j-=h;
}
list[j]=temp;
}
}
7

Ngo Huu Phuc, Le Quy Don Technical University



7.1. ShellSort (6/8)
 Tính hiệu quả của thuật toán ShellSort?
 Phụ thuộc vào mảng khoảng cách.
 Dạng mặc định, do Shell đề xuất:
 ht = N/2, hk = hk+1/2 …
 Độ phức tạp của thuật toán - O(N2)

8

Ngo Huu Phuc, Le Quy Don Technical University


7.1. ShellSort (7/8)
 Dãy khoảng cách của Hibbards:
 Hk = 2k-1 i.e. 1, 3, 7,
 Độ phức tạp: O(N1.5)
 Dãy khoảng cách của Sedgewicks:
 Có một số dạng được giới thiệu, nổi tiếng trong

đó có 2 dạng:
9 * 4i – 9 * 2i + 1, và 4i – 3 * 2i + 1
 Độ phức tạp: O(N4/3)

9

Ngo Huu Phuc, Le Quy Don Technical University


7.1. ShellSort (8/8)

 Độ phức tạp của ShellSort trong trường hợp tồi nhất:

O(N2)
 Độ phức tạp của ShellSort trong trường hợp tốt nhất:

~ O(N)
 Độ phức tạp của ShellSort trong trường hợp trung

bình: ~ O(N7/6)

10

Ngo Huu Phuc, Le Quy Don Technical University


7.2. Mergesort (1/9)
 MergeSort là một thuật toán sắp xếp cho độ phức

tạp tương đương với Quick Sort.
Ý tưởng:
 Ý tưởng cơ bản của MergeSort là nối 2 mảng đã

sắp xếp với kích thước m và n thành mảng mới
có kích thước (m+n).

11

Ngo Huu Phuc, Le Quy Don Technical University



7.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!!!
12

Ngo Huu Phuc, Le Quy Don Technical University


7.2. Mergesort (3/9)

Hoạt động của thuật toán MergeSort
13

Ngo Huu Phuc, Le Quy Don Technical University


7.2. Mergesort (4/9)

Để thực hiện được thuật toán này cần thiết xây
dựng:
 Một hàm cho phép nối 2 mảng có kích thước m và n

thành mảng có kích thước (m+n).
 Cần thêm một hàm cho biết đã nối các mảng liền kề hay

chưa?

14

Ngo Huu Phuc, Le Quy Don Technical University


7.2. Mergesort (5/9)
#include <conio.h>

mergesort(list,n-1);

#include <stdio.h>

printf("Cac phan tu cua mang sau khi sap
xep:\n");

#include <stdlib.h>
#include <time.h>

printlist(list,n);

#define MAX 100


getch();

void readlist(int list[],int n);

}

void printlist(int list[],int n);

void readlist(int list[],int n)

void merge(int list[],int listtemp[],int k,int m,int n);

{

void mpass(int list[],int listtemp[],int l,int n);

int i;

void mergesort(int list[], int n );

printf("Nhap cac phan tu cho mang\n");

void main() {

srand( (unsigned)time(NULL));

int list[MAX], n;

for(i=0;i


printf("Nhap so phan tu cho mang\n");
scanf("%d",&n);

//scanf("%d",&list[i]);

readlist(list,n);

list[i]=rand();

printf("Cac phan tu cua mang truoc khi sap
xep:\n");
printlist(list,n);
15

Ngo Huu Phuc, Le Quy Don Technical University

}


7.2. Mergesort (6/9)
void printlist(int list[],int n)
{

while( i <= m && j <= n)
{

int i;

if(list[i] <= list[j])


printf("Cac phan tu trong danh sach: \n");

{

for(i=0;i
listtemp[k] = list[i];

printf("%d\t",list[i]);

i++;

printf("\n");

k++;

}
// Noi 2 mang da sap xep

}

// Mang thu nhat: tu phan tu thu k den phan tu thu m

else

// Mang thu nhat: tu phan tu thu m+1 den phan tu

{


// thu n

listtemp[k] = list[j];

void merge(int list[],int listtemp[],int k,int m,int n)

j++;

{

k++;
int i,j;

}

i=k;
j = m+1;

16

Ngo Huu Phuc, Le Quy Don Technical University

}


7.2. Mergesort (7/9)
while(i <= m)
{

// Voi do dai l cua moi mang con

// noi cac mang con thanh mang lon hon

listtemp[k] = list[i];

void mpass( int list[],int listtemp[],int l,int n) {

i++;

int i;

k++;

i = 0;

}

while( i <= (n-2*l+1))

while (j <= n )

{

merge(list,listtemp,i,(i+l-1),(i+2*l-1));

{

i = i + 2*l;

listtemp[k] = list[j];


}

if((i+l-1) < n)

j++;

merge(list,listtemp,i,(i+l-1),n);

k++;
}

else

}

while (i <= n )

{

listtemp[i] = list[i];
i++;
}
}
17

Ngo Huu Phuc, Le Quy Don Technical University


7.2. Mergesort (8/9)
void mergesort(int list[], int n )

{
int l;
int listtemp[MAX];
l =1;
while (l <= n )
{
mpass(list,listtemp,l,n);
l = l*2;
mpass(listtemp,list,l,n);
l = l*2;
}
}

18

Ngo Huu Phuc, Le Quy Don Technical University


7.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 log2(n)), tuy nhiên cần sử dụng thêm một mảng có
kích thước n nữa

19

Ngo Huu Phuc, Le Quy Don Technical University


7.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.
20

Ngo Huu Phuc, Le Quy Don Technical University


7.3. Bucket sort (2/6)

4

2

1

2

0

0
0
0

0
21

0

3

2

2
2
2
2

1
1


0

1

1

1

2

2

Ngo Huu Phuc, Le Quy Don Technical University

4

0

3
3

2

2

2

3


0

4
4

3

3

4

4


7.3. Bucket sort (3/6)
#include <stdio.h>

printlist(list,n);

#include <conio.h>
#define MAX 100
int inputdata(int* list,int n);
void printlist(int* list,int n);
void bucketsort(int *list, int n, int m);
void main() {
int list[MAX], n;

}
int inputdata(int* list,int n)
{

int i, m;
int temp;

// So thung

printf("Nhap cac phan tu duong cho mang\n");

int m;

do {

printf("Nhap so phan tu cho mang, toi da =
100\n");
scanf("%d",&n);
m = inputdata(list,n);
printf("Mang da nhap:\n");
printlist(list,n);
bucketsort(list,n,m);
printf("Mang da sap xep:\n");
22

getch();

Ngo Huu Phuc, Le Quy Don Technical University

scanf("%d",&temp);
} while (temp<0);
m = temp;
list[0] = temp;
for(i=1;i

{


7.3. Bucket sort (4/6)
do {

void bucketsort(int *list, int n, int m)
scanf("%d",&temp);

{

} while (temp<0);

int i,j,k;

list[i] = temp;

int bucket[MAX];

if (m
// Khoi tao thung

}

for(j=0; j<=m; j++)

return m;

bucket[j] = 0;


}

for(i=0; i
void printlist(int* list,int n)

bucket[list[i]]++;

{
int i;

i = 0;

printf("Cac phan tu cua mang: \n");

for(j=0; j<=m; j++)

for(i=0;i
for(k=0; k
printf("%d\t",list[i]);

{

printf("\n");

list[i] = j;


}

i++;
}
}

23

Ngo Huu Phuc, Le Quy Don Technical University


7.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)

24

Ngo Huu Phuc, Le Quy Don Technical University



7.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<
 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.

25

Ngo Huu Phuc, Le Quy Don Technical University


×