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

Bài giảng cấu trúc dữ liệu và giải thuật chương 3 ths thiều quang trung

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 (1.17 MB, 61 trang )

CHƯƠNG 3
CÁC THUẬT TOÁN SẮP XẾP
GV Th.S. Thiều Quang Trung
Trường Cao đẳng Kinh tế Đối ngoại


Nội dung

1
2
3
4
5
6

• Chọn trực tiếp - Selection Sort
• Chèn trực tiếp - Insertion Sort
• Đổi chỗ trực tiếp - Interchange Sort
• Nổi bọt - Bubble Sort
• Sắp xếp dựa trên phân hoạch - Quick Sort

• Trộn trực tiếp - Merge Sort
GV. Thiều Quang Trung

2


Các khái niệm
• Sắp xếp là gì ?
– Sắp xếp là quá trình xử lý một danh sách các phần
tử (hoặc các mẫu tin) để đặt chúng theo một thứ


tự thỏa mãn một tiêu chuẩn nào đó.

• Khái niệm nghịch thế:
– Xét một mảng các số a0, a1, … ,aN
– Giả sử xét mảng có thứ tự tăng dần, nếu có i < j và
ai > aj, thì ta gọi đó là nghịch thế.

GV. Thiều Quang Trung

3


Các khái niệm
• Để sắp xếp một mảng => tìm cách giảm số các
nghịch thế trong mảng này bằng cách hoán vị
các cặp phần tử.
• Cho trước một dãy số a1, a2, … aN được lưu trữ
trong cấu trúc dữ liệu mảng.
Ví dụ: int a[N];
=> Chọn lựa một số phương pháp để sắp xếp.

GV. Thiều Quang Trung

4


Chọn trực tiếp - Selection Sort
• Ý tưởng: thực hiện N-1 lần việc đưa phần tử nhỏ
nhất trong dãy hiện hành về vị trí đứng ở đầu dãy
• Nhận xét: nếu mảng có thứ tự thì phần tử ai luôn

là min (ai,ai+1,..,an-1) => Ý tưởng của thuật toán
chọn trực tiếp:
– 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 đầu dãy hiện hành;
– Sau đó không quan tâm phần tử này nữa, 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 … cho đến khi
dãy hiện hành chỉ còn một phần tử.
GV. Thiều Quang Trung

5


Chọn trực tiếp (tt)
• Giải thuật :
B1: i = 0;
B2: Tìm phần tử a[min] nhỏ nhất trong dãy hiện hành
từ a[i] đến a[n]
B3: if (min ≠ i) : hoán vị a[min] và a[i]
B4: if (i≤ (n-1):
B4.1: i++
B4.2: Lặp lại B2
Ngược lại : dừng // vì n-1 phần tử đã nằm đúng vị trí
GV. Thiều Quang Trung

6


1. Chọn trực tiếp (tt)


GV. Thiều Quang Trung

77


1. Chọn trực tiếp (tt)

GV. Thiều Quang Trung

88


Cài đặt giải thuật Chọn trực tiếp
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{
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]);
}
}
GV. Thiều Quang Trung

9



Đánh giá giải thuật Chọn trực tiếp
• Ở lượt thứ I, cần (n-i) lần so sánh để tìm 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 ban đầu.
n−1
n(n − 1)
(n

i)
=
• Trong mọi trường hợp số lần so sánh là 
2
i =1
• 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ố.
Trường hợp

Số lần so sánh

Số phép gán

Tốt nhất

n(n − 1)
2

0


Xấu nhất

n(n − 1)
2
GV. Thiều Quang Trung

3n(n − 1)
2
10


Chèn trực tiếp - Insertion Sort
Ý tưởng:
• Giả sử dãy {a0,a1,…an-1} có k phần tử đầu tiên
{a0,a1,…ak-1} đã có thứ tự.
• Chèn phần tử ak vào k phần tử đầu tiên đã có
thứ tự bằng cách tìm vị trí đúng của phần tử k
theo giải thuật tìm tuần tự (Sequential Search)
→ có dãy mới {a0,a1,…,ak-1,ak} có thứ tự.
• Vị trí cần chèn ak chính là giữa 2 phần tử ai-1 và ai
sao cho ai-1 ≤ ak+1 ≤ ai
GV. Thiều Quang Trung

11


Chèn trực tiếp - Insertion Sort (tt)
Thuật toán:
B1: k = 1 //Giả sử đoạn a[0] đã sắp xếp
B2: x = ak Tìm vị trí pos thích hợp trong đoạn a0 đến ak-1 để

chèn ak vào
B3: Dời chỗ các phần tử từ apos đến ak-1 sang phải 1 vị trí để
dành chỗ cho ak
B4: apos = x; // đoạn a0 … ak đã được sắp
B5: k = k+1
Nếu i<= n: lặp lại B2
Ngược lại : dừng

GV. Thiều Quang Trung

12


Ví dụ mô phỏng chèn trực tiếp


Cho dãy số a : N = 8 ;
12
2
8
5

1

GV. Thiều Quang Trung

6

4


15

13
13


Ví dụ mô phỏng chèn trực tiếp (tt)

GV. Thiều Quang Trung

14
14


Cài đặt giải thuật Chèn trực tiếp
void InsertionSort (int a [ ], int n)
{ int k=0, i;
while (a[k]≤a[k+1] && kwhile (k{
int x=a[k+1]; i=k;
while (x<a[i] && i>0)
{
a[i+1] = a[i];
i--;
}
a[i+1]=x;
k++;
} return;
}

GV. Thiều Quang Trung

15


Đánh giá giải thuật Chèn trực tiếp
• Trường hợp tốt nhất: khi mảng a ban đầu đã
có thứ tự tăng
– Số phép gán: Gmin = 2*(n-1)
– Số phép so sánh: Smin = 1+2+…+ (n-1) = n*(n-1)/2

• Trường hợp xấu nhất: khi mảng a ban đầu
luôn có phần tử nhỏ nhất trong n-k phần tử
còn lại
– Số phép gán: Gmax = 2*(n-1) + n*(n-1)/2
– Số phép so sánh: Smax = n-1

• Độ phức tạp của thuật toán: O(n2)
GV. Thiều Quang Trung

16


Chèn nhị phân – Binary Insertion Sort
Ý tưởng:
• Phương pháp chèn nhị phân tương tự
phương pháp chèn trực tiếp.
• Tuy nhiên, khi thực hiện tìm kiếm vị trí i cho
phần tử ai để chèn vào đoạn {a0,a1,…,ai-1} có
thể dùng phương pháp tìm kiếm nhị phân

(Binary Search) thay cho tìm kiếm tuần tự
(Sequential Search)

GV. Thiều Quang Trung

17


Cài đặt Binary Insertion Sort
void BinaryInsertionSort(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=0 ; i{
x = a[i]; l = 0; 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
}
}
GV. Thiều Quang Trung


18


Đánh giá Binary Insertion Sort
• Phương pháp chèn nhị phân chỉ cải tiến cách
tìm kiếm vị trí thích hợp của phần tử a[i],
làm giảm số lần so sánh nhưng lại không làm
thay đổi số lần di chuyển.
• Vì vậy việc cải tiến này không đáng kể lắm →
Độ phức tạp của thuật toán vẫn là O(n2)

GV. Thiều Quang Trung

19


Đổi chỗ trực tiếp - Interchange Sort
• Ý tưởng :
Ý tưởng chính của giải thuật là xuất phá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.

GV. Thiều Quang Trung

20
20



3. Đổi chỗ trực tiếp (tt)
• Giải thuật :
B1 : i = 1 ; // Bắt đầu từ đầu dãy.
B2 : j = i + 1 ; // Tìm các phần tử a[j] < a[i], j > i
B3 : Trong khi j  n thực hiện
Nếu a[j] < a[i] : Hoán vị a[i] và a[j] ;
j = j +1;
B4 :i = i+1;
Nếu i < n : lặp lại Bước 2.
Ngược lại : Dừng.
GV. Thiều Quang Trung

21
21


Ví dụ mô phỏng Đổi chỗ trực tiếp
• Cho dãy số a : N = 8 ;
12
2
8
5
1

6

GV. Thiều Quang Trung

4


15

22
22


Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

GV. Thiều Quang Trung

23
23


Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

GV. Thiều Quang Trung

24
24


Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

GV. Thiều Quang Trung

25
25



×