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

Các phương pháp sắp xếp thông dụng

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 (3.24 MB, 83 trang )

25
25
Khái niệm nghòch thế
• Khái niệm nghòch thế:
– Xét một mảng các số a
0
, a
1
, … a
n
.
– Nếu có i<j và a
i
> a
j
, thì ta gọi đó là một nghòch
thế.
• Mảng chưa sắp xếp sẽ có nghòch thế.
• Mảng đã có thứ tự sẽ không chứa nghòch thế.
a
0

≤≤
≤ a
1

≤≤
≤ … ≤
≤≤
≤ a
n


26
26
Các phương pháp sắp xếp thông dụng
• Selection sort
• Insertion sort
• Interchange sort
• Bubble sort
• Shaker sort
• Binary Insertion
sort
• Shell sort
• Heap sort
• Quick sort
• Merge sort
• Radix sort
• …
Đ
Đ
ơn gia
ơn gia
û
û
n,
n,
Chi ph
Chi ph
í
í
cao
cao

Ph
Ph


c ta
c ta
ï
ï
p hơn
p hơn
Hie
Hie
ä
ä
u qua
u qua
û
û
cao
cao


ù
ù
p thua
p thua
ä
ä
t toa
t toa

ù
ù
n
n
kha
kha
ù
ù
c
c
27
27
Selection sort – Ý tưởng
• Nhận xét: Mảng có thứ tự thì
a
i
= min(a
i
, a
i+1
, …, a
n-1
)


Ý tưởng: mô phỏng một trong những cách sắp
xếp tự nhiên nhất trong thực tế:
– Chọn phần tử nhỏ nhất trong N phần tử ban đầu,
đưa phần tử này về vò trí đúng là đầu dãy hiện
hành

– Xem dãy hiện hành chỉ còn N-1 phần tử của dãy
ban đầu, bắt đầu từ vò trí thứ 2; lặp lại quá trình
trên cho dãy hiện hành... đến khi dãy hiện hành
chỉ còn 1 phần tử.
28
28
Selection sort – Thuật toán
//input: dãy (a, N)
//output: dãy (a, N) đã được sắp xếp
• Bước 1 : i = Vò trí đầu;
• Bước 2 : Tìm phần tử a[min] nhỏ nhất trong dãy
hiện hành từ a[i] đến a[N]
• Bước 3 : Nếu min

≠≠
≠ i: Hoán vò a[min] và a[i]
• Bước 4 : Nếu i chưa là Vò trí cuối
» i = Vò trí kế(i);
» Lặp lại Bước 2
Ngược lại: Dừng. //N phần tử đã nằm
đúng vò trí.
29
29
Selection sort – Ví duï
2 8 5 1 6 4 1512
i
min
2 3 4 5 6 7 81
Find MinPos(1, 8)
Swap(a

i
, a
min
)
30
30
Selection sort – Ví duï
2 8 5 12 6 4 151
i
min
2 3 4 5 6 7 81
Find MinPos(2, 8)
Swap(a
i
, a
min
)
31
31
Selection sort – Ví duï
2 8 5 12 6 4 151
i
min
2 3 4 5 6 7 81
Find MinPos(3, 8)
Swap(a
i
, a
min
)

32
32
Selection sort – Ví duï
2 4 5 12 6 8 151
i
min
2 3 4 5 6 7 81
Find MinPos(4, 8)
Swap(a
i
, a
min
)
33
33
Selection sort – Ví duï
2 4 5 12 6 8 151
i
min
2 3 4 5 6 7 81
Find MinPos(5, 8)
Swap(a
i
, a
min
)
34
34
Selection sort – Ví duï
2 4 5 6 12 8 151

i
min
2 3 4 5 6 7 81
Find MinPos(6, 8)
Swap(a
i
, a
min
)
35
35
Selection sort – Ví dụ
2 4 5 6 8 12 151
i
min
2 3 4 5 6 7 81
Find MinPos(7, 8)
Swap(a
i
, a
min
)
12
15
36
36
Selection sort
void SelectionSort(int a[],int N )
{
int min; // chỉ số phần tử nhỏ nhất trong dãy hiện hành

for (int i=0; i<N-1 ; i++)
{
min = i;
for(int j = i+1; j < N ; j++)
if (a[j] < a[min])
min = j; // ghi nhận vò trí phần tử nhỏ nhất
if (min != i)
Swap(a[min], a[i]);
}
}
37
37
• Số lần hoán vò (một hoán vò bằng 3 phép
gán) phụ thuộc vào tình trạng ban đầu
của dãy số
Selection sort – Đánh giá giải thuật
38
38
Selection sort – Đánh giá giải thuật
• Ởû lượt thứ i, cần (N-i) lần so sánh để xác
đònh phần tử nhỏ nhất hiện hành.
• Số lượng phép so sánh không phụ thuộc vào
tình trạng của dãy số ban đầu.
• Trong mọi trường hợp, số lần so sánh là:
2
1)n(n
i)(n
1n
1i


=−


=
39
39
Insertion Sort – Ý tưởng
• Nhận xét: mọi dãy a
1
, a
2
,..., a
n
luôn có i-1 phần tử
đầu tiên a
1
, a
2
,... ,a
i-1
đã có thứ tự (2 ≤ i).


Ý tưởng chính: tìm cách chèn phần tử a
i
vào vò trí
thích hợp của đoạn đã được sắp để có dãy mới a
1
,
a

2
,... ,a
i
trở nên có thứ tự.
– Vò trí này chính là pos thỏa a
pos-1
≤ a
i
< a
pos
(1≤
≤≤
≤pos≤
≤≤
≤i).
Chi tiết hơn:
– Dãy ban đầu a
1
, a
2
,..., a
n
, xem như đã có đoạn gồm một
phần tử a
1
đã được sắp.
– Thêm a
2
vào đoạn a
1

sẽ có đoạn a
1
a
2
được sắp
– Thêm a
3
vào đoạn a
1
a
2
để có đoạn a
1
a
2
a
3
được sắp
– Tiếp tục cho đến khi thêm xong a
N
vào đoạn a
1
a
2 ...
a
N-1
sẽ
có dãy a
1
a

2....
a
N
được sắp.
40
40
Insertion Sort – Thuật toán
//input: dãy (a, N)
//output: dãy (a, N) đã được sắp xếp
• Bước 1
: i = 2; // giả sử có đoạn a[1] đã được sắp
• Bước 2
: x = a[i]; Tìm vò trí pos thích hợp trong đoạn
a[1]
đến a[i] để chèn x vào
• Bước 3
: Dời chỗ các phần tử từ a[pos] đến a[i-1] sang
phải 1 vò trí để dành chổ cho x
• Bước 4
: a[pos] = x; // có đoạn a[1]..a[i] đã được sắp
• Bước 5
: i = i+1;
Nếu i ≤
≤≤
≤ n : Lặp lại Bước 2.
Ngược lại : Dừng.
41
41
Insertion Sort – Ví duï
2 8 5 1 6 4 1512

2 3 4 5 6 7 81
42
42
2 8 5 1 6 4 1512
i
x
2 3 4 5 6 7 81
pos
2
Insertion Sort – Ví duï
Insert a
2
into (1, 2)
43
43
12 8 5 1 6 4 152
i
x
2 3 4 5 6 7 81
pos
Insertion Sort – Ví duï
Insert a
3
into (1, 3)
8
44
44
8 12 5 1 6 4 152
i
x

2 3 4 5 6 7 81
pos
Insertion Sort – Ví duï
Insert a
4
into (1, 4)
5
45
45
5 8 12 1 6 4 152
i
x
2 3 4 5 6 7 81
pos
Insertion Sort – Ví duï
Insert a
5
into (1, 5)
1
46
46
2 5 8 12 6 4 151
i
x
2 3 4 5 6 7 81
pos
Insertion Sort – Ví duï
Insert a
6
into (1, 6)

6
47
47
2 5 6 8 12 4 151
i
x
2 3 4 5 6 7 81
pos
Insertion Sort – Ví duï
Insert a
7
into (1, 7)
4
48
48
2 4 5 6 8 12 151
i
x
2 3 4 5 6 7 81
pos
Insertion Sort – Ví duï
Insert a
8
into (1, 8)
15
49
49
2 4 5 6 8 12 151
pos
2 3 4 5 6 7 81

Insertion Sort – Ví dụ
50
50
Insertion Sort – Cài đặt
void InsertionSort(int a[], int N )
{
int pos, i;
int x;
//lưu trữ a[i] tránh bò ghi đè khi dời chỗ các phần tử.
for(int i=1 ; i<N ; i++) //đoạn a[0] đã sắp
{
x = a[i];
for(pos=i;(pos>0)&&(a[pos-1]>x);pos--)
a[pos] = a[pos-1];
a[pos] = x;// chèn x vào dãy
}
}
51
51
Insertion Sort – Nhận xét
• Khi tìm vò trí thích hợp để chèn a[i] vào đoạn
a[0] đến a[i-1], do đoạn đã được sắp 

 có thể
sử dụng giải thuật tìm nhò phân để thực hiện
việc tìm vò trí pos 

 giải thuật sắp xếp chèn
nhò phân Binary Insertion Sort
– Lưu ý: Chèn nhò phân chỉ làm giảm số lần so sánh,

không làm giảm số lần dời chỗ.
• Ngoài ra, có thể cải tiến giải thuật chèn trực
tiếp với phần tử cầm canh để giảm điều kiện
kiểm tra khi xác đònh vò trí pos.
52
52
Binary Insertion Sort – Cài đặt
void BInsertionSort(int a[], int N )
{
int l,r,m,i;
int x;//lưu trữ giá trò a[i] tránh bò ghi đè khi dời chỗ các phần
tử.
for(int i=1 ; i<N ; i++)
{ x = a[i]; l = 1; r = i-1;
while(l<=r) // tìm vò trí chèn x
{ m = (l+r)/2; // tìm vò trí thích hợp m
if(x < a[m]) r = m-1;
else l = m+1;
}
for(int j = i ; j >l ; j--)
a[j] = a[j-1]; // dời chỗ các phần tử sẽ đứng sau
x
a[l] = x; // chèn x vào dãy
}
}
53
53
Insertion Sort – Đánh giá giải thuật
• Các phép so sánh xảy ra trong mỗi vòng lặp tìm vò trí
thích hợp pos. Mỗi lần xác đònh vò trí pos đang xét

không thích hợp 

 dời chỗ phần tử a[pos-1] đến vò trí
pos.
• Giải thuật thực hiện tất cả N-1 vòng lặp tìm pos, do số
lượng phép so sánh và dời chỗ này phụ thuộc vào tình
trạng của dãy số ban đầu, nên chỉ có thể ước lược trong
từng trường hợp như sau:
Phương pháp đổi chỗ trực tiếp
Interchange Sort
55
55
Interchange Sort – Ý tưởng
• Nhận xét: Để sắp xếp một dãy số, ta có
thể xét các nghòch thế có trong dãy và
làm triệt tiêu dần chúng đi.


 Ý tưởng chính:
– Xuất phát từ đầu dãy, tìm tất cả nghòch thế
chứa phần tử này, triệt tiêu chúng bằng
cách đổi chỗ phần tử này với phần tử tương
ứng trong cặp nghòch thế.
– Lặp lại xử lý trên với các phần tử tiếp theo
trong dãy
56
56
Interchange Sort – Thuật toán
//input: dãy (a, N)
//output: dãy (a, N) đã được sắp xếp

• Bước 1 : i = 1; // bắt đầu từ đầu dãy
• Bước 2 : j = i+1; //tìm các cặp phần tử a[j] <
a[i], j>i
• Bước 3 : Trong khi j ≤
≤≤
≤ N thực hiện
• Nếu a[j]<a[i]: a[i]↔
↔↔
↔a[j];
• j = j+1;
• Bước 4 : i = i+1;
– Nếu i < n: Lặp lại Bước 2.
– Ngược lại: Dừng.
57
57
Interchange Sort – Ví duï
2 8 5 1 6 4 1512
2 3 4 5 6 7 81
i
j
1
58
58
Interchange Sort – Ví duï
12 8 5 2 6 4 151
2 3 4 5 6 7 81
i
j
2
59

59
Interchange Sort – Ví duï
2 12 8 5 6 4 151
2 3 4 5 6 7 81
i
j
4
60
60
Interchange Sort – Ví duï
2 4 12 8 6 5 151
2 3 4 5 6 7 81
i
j
5
61
61
Interchange Sort – Ví dụ
2 4 5 6 8 12 151
2 3 4 5 6 7 81
62
62
Interchange Sort - Cài đặt
void InterchangeSort(int a[], int N)
{
int i, j;
for (i = 0 ; i<N-1 ; i++)
for (j =i+1; j < N ; j++)
if(a[j]< a[i]) //nếu có nghòch thế
thì đổi chỗ

Swap(a[i],a[j]);
}
63
63
Interchange Sort
Đánh giá giải thuật
• Số lượng các phép so sánh xảy ra không phụ
thuộc vào tình trạng của dãy số ban đầu
• Số lượng phép hoán vò thực hiện tùy thuộc
vào kết quả so sánh
Phương pháp nổi bọt
Bubble sort
65
65
Bubble sort – Ý tưởng
• Ý tưởng chính:
– Xuất phát từ cuối (đầu) dãy, đổi chỗ các
cặp phần tử kế cận để đưa phần tử nhỏ
(lớn) hơn trong cặp phần tử đó về vò trí
đúng đầu (cuối) dãy hiện hành, sau đó sẽ
không xét đến nó ở bước tiếp theo,
– Ở lần xử lý thứ i có vò trí đầu dãy là i
– Lặp lại xử lý trên cho đến khi không còn
cặp phần tử nào để xét.
66
66
Bubble sort – Thuật toán
//input: dãy (a, N)
//output: dãy (a, N) đã được sắp xếp
• Bước 1 : i = Vò trí đầu;

• Bước 2 : j = Vò trí cuối;//Duyệt từ cuối dãy ngược
về vò trí i
– Trong khi (j > i) thực hiện:
• Nếu a[j]<a[j-1]: a[j]↔
↔↔
↔a[j-1];//xét cặp phần tử kế cận
• j = Vò trí trước(j);
• Bước 3 : i = Vò trí kế(i); // lần xử lý kế tiếp
– Nếu i = Vò trí cuối: Dừng. // Hết dãy.
– Ngược lại : Lặp lại Bước 2.
67
67
Bubble Sort – Ví duï
2 8 5 1 6 4 1512
2 3 4 5 6 7 81
i
j
1
68
68
Bubble Sort – Ví duï
12 2 8 5 4 6 151
2 3 4 5 6 7 81
i
j
2
69
69
Bubble Sort – Ví duï
2 12 4 8 5 6 151

2 3 4 5 6 7 81
i
j
4
70
70
Bubble Sort – Ví duï
2 4 12 8 5 6 151
2 3 4 5 6 7 81
i
j
5
71
71
Bubble Sort – Ví duï
2 4 5 12 8 6 151
2 3 4 5 6 7 81
i
j
6
72
72
Bubble Sort – Ví duï
2 4 5 6 12 8 151
2 3 4 5 6 7 81
i
j
8
73
73

Bubble Sort Vớ duù
2 4 5 6 8 12 151
2 3 4 5 6 7 81
i
j
15
12
74
74
Bubble sort - Caứi ủaởt
void BubbleSort(int a[], int N)
{
int i, j;
for (i = 0 ; i < N-1 ; i++)
for (j = N-1; j>i ; j --)
if(a[j]< a[j-1])
Swap(a[j], a[j-1]);
}

×