Đổ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 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
Trang 2Mục tiêu
Nắm vững, minh họa và tính toán được các
phép gán (hoán vị) các giải thuật sắp xếp cơ bản trên mảng một chiều
Cài đặt được các giải thuật bằng ngôn ngữ C/
C++
2
Trang 3Các khái niệm
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 đó dựa trên nội dung thông tin lưu giữ tại mỗi phần tử.
Khái niệm nghịch thế
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ế
Mục tiêu của sắp xếp là khử các nghịch thế (bằng cách hoán vị)
3
a 1 a 2 a 3 a 4 … … a N-2 a N-1 a N
Trang 4Các giải thuật sắp xếp cơ bản
Đổi chổ trực tiếp – Interchange Sort
Chọn trực tiếp – Selection Sort
Chèn trực tiếp – Insertion Sort
Nổi bọt – Bubble Sort
Quick Sort
Một số giải thuật khác đọc thêm trong tài liệu
4
Trang 5Đổ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 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
xử lý trên với các phần tử tiếp theo trong dãy
5
Trang 212
Trang 273
Trang 325
Trang 36Bước 5: Xét phần tử thứ năm (tại vị trí 5)
7
7
Trang 399
Trang 4110
Trang 43Giải thuật
Bước 1 : i = 1;// bắt đầu từ đầu dãy
Bước 2 : j = i+1;//tìm các 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]: Hoán vị a[i], a[j];
Trang 45Bài tập
Minh họa từng bước thực hiện của giải thuật Interchange Sort khi sắp dãy số sau tăng dần:
Cho biết tổng số phép hoán vị
45
Trang 46 Ðá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, nhưng
số lượng phép hoán vị thực hiện tùy thuộc vào kết quả so sánh, có thể ước lượng trong từng trường hợp như sau:
46
Trang 47Chọn trực tiếp – selection sort
Ý tưởng:
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; lúc này dãy hiện hành chỉ còn N-1 phần tử cần sắp xếp, 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ử
47
Trang 48Chọn trực tiếp – selection sort
48
Làm sao để xác định được vị trí phần tử
tử?
?
Trang 50vtmin
Trang 515 nhỏ hơn 10 nên cập nhật
vị trí min
10
10
Trang 527 lớn hơn 5 nên không cập nhật vị trí min
10
10
5
5 7 7
Trang 533 nhỏ hơn 5 nên cập nhật
Trang 549 lớn hơn 3 nên không cập nhật vị trí min
10
10
5
5 7 7
Trang 551 nhỏ hơn 3 nên cập nhật
Trang 5615 lớn hơn 1 nên không cập nhật vị trí min
Trang 572
1
1
Trang 58Chọn trực tiếp – selection sort
Tìm vị trí phần tử nhỏ nhất?
58
Hãy cài đặt hàm tìm và trả về vị trí của phần tử nhỏ nhất bằng ngôn ngữ C, đầu vào
là mảng số nguyên a, kích thước N?
?
Trang 59Chọn trực tiếp – selection sort
Tìm vị trí phần tử nhỏ nhất?
59
Giả sử cần tìm vị trí phần tử nhỏ nhất bắt đầu từ vị trí k cho trước (ví dụ đoạn
từ 3 đến 8) thì giải quyết như thế nào? Hãy
viết hàm cài đặt bằng ngôn ngữ C?
Trang 68Kết thúc giải thuật - hoàn tất sắp xếp
Trang 73 Ðánh giá giải thuật
Ðối với giải thuật chọn trực tiếp, có thể thấy rằng ở lượt thứ i, bao giờ cũng 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 này không phụ thuộc vào tình trạng của dãy số ban đầu, do vậy trong mọi trường hợp có thể kết luận :
73
Trang 74Nổi bọt – bubble sort
Ý tưởng:
Xuất phát từ cuối dãy, đổi chỗ các cặp phần
tử kế cận để đưa phần tử nhỏ hơn trong cặp phần tử đó về vị trí đúng đầu dãy hiện hành, sau đó sẽ không xét đến nó ở bước tiếp theo, do vậy ở lần xử lý thứ i sẽ 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
74
Trang 751 2 3 4 5 6 7
8
75
7 3 9 2 15 1
10 5 i
j
Trang 761 2 3 4 5 6 7
8
76
7 3 9 2 15
1 10 5 i
j
Trang 771 2 3 4 5 6 7
8
77
7 3 9 2
15
1
10 5 i
j
Trang 781 2 3 4 5 6 7
8
78
7 3
9 2
15
1
10 5 i
j
Trang 791 2 3 4 5 6 7
8
79
7 3
9 2
15
1
10
5 i
j
Trang 801 2 3 4 5 6 7
8
80
7 3
9 2
15
1
10
5 i
j
Trang 811 2 3 4 5 6 7
8
81
7 3
9 2
Trang 821 2 3 4 5 6 7
8
82
7 3
9 2
Trang 83Trong khi (j > i) thực hiện:
Nếu a[j]<a[j-1]: Hoán vị a[j] và a[j-1]
Trang 84if(a[j]< a[j-1])
HoanVi(a[j],a[j-1]);
}}
Trang 85Đánh giá giải thuật
Trong mọi trường hợp, số phép so sánh là:
Trang 86Các giải thuật sắp xếp cơ bản
Đổi chổ trực tiếp – Interchange Sort
Chọn trực tiếp – Selection Sort
Nổi bọt – Bubble Sort
Chèn trực tiếp – Insertion Sort
Quick Sort
86
Trang 87Chèn trực tiếp – insertion sort
Ý tưởng
Cho dãy ban đầu a 1 , a 2 , ,a n, ta có thể xem như
đã có đoạn gồm một phần tử a 1 đã được sắp, sau
đó thêm a 2 vào đoạn a 1 sẽ có đoạn a 1 a 2 được
sắp; tiếp tục 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
87
Trang 97Chèn trực tiếp – insertion sort
Trang 99void InsertionSort(int a[], int N )
Trang 101 Đánh giá giải thuật
Các phép so sánh xảy ra trong mỗi vòng lặp while tìm
vị trí thích hợp pos, và mỗi lần xác định vị trí đang xét
không thích hợp, sẽ dời chỗ phần tử a[pos] tương ứng
Giải thuật thực hiện tất cả N-1 vòng lặp while, 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ượng trong từng trường hợp như sau:
101
Trang 102Kết luận
“Chèn trực tiếp” và “Chọn trực tiếp” đều có chi phí cho trường hợp xấu nhất là O(n 2 ) do đó,
không thích hợp cho việc sắp xếp các mảng lớn
Dễ cài đặt, dễ kiểm lỗi
“Chèn trực tiếp” tốt hơn “Chọn trực tiếp”, nhất là khi mảng đã có thứ tự sẵn
Cần có những giải thuật hiệu quả hơn cho việc sắp
Trang 103Các giải thuật sắp xếp cơ bản
Đổi chỗ trực tiếp – Interchange Sort
Chọn trực tiếp – Selection Sort
Nổi bọt – Bubble Sort
Chèn trực tiếp – Insertion Sort
Quick Sort
103
Trang 106L=1 R=3
L=4 R=8 Đoạn 1 Đoạn 2
7 3 9 2 15 1
10 5
Trang 107L=5 R=8
Đoạn 1 Đoạn 2
3 7 9 5 15 10
1 2
Trang 1083 5 9 7 15 10
1 2
Trang 1093 5 7 9 15 10
1 2
Trang 1111 2 3 4 5 6 7 8
111
Đoạn cần sắp xếp
i j i=4, j=5 x
Trang 1131 2 3 4 5 6 7 8
113
Đoạn cần sắp xếp
i j i=3, j=4 x
Trang 114Kết thúc
Trang 115 Nếu (L<j) Phân hoạch dãy aL … aj
Nếu (i<R) Phân hoạch dãy ai … aR
115
Trang 116Giải thuật phân hoạch dãy a L , a L+1 , … a R thành 2 dãy con
Bước 1.2b: Trong khi (a[j]>x)
Bước 1.2c: Nếu (i≤j): Hoán vị a[i] và a[j]; i++,
j Bước 1.3:
Nếu i<j: Lặp lại bước 1.2
Trang 117Cài đặt
void QuickSort(int a[], int left, int right)
{ int i, j, x; x=a[(left+right)/2];i=left, j=right;
do{ while(a[i]<x) i++;
if(left<j) QuickSort(a, left, j);
if(i<right) QuickSort(a, i, right);
Trang 119Đánh giá giải thuật
Chi phí trung bình O(n*log 2 n)
Chi phí cho trường hợp xấu nhất O(n 2 )
Chi phí tùy thuộc vào cách chọn phần tử
“trục”:
Nếu chọn được phần tử có giá trị trung bình,
ta sẽ chia thành 2 dãy bằng nhau;
Nếu chọn nhằm phần tử nhỏ nhất (hay lớn nhất) O(n2)
119