Đổ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ừ đầudãy, tìm tất cả nghịch thế chứa phần tử này, triệttiêu chúng bằng cách đổi chỗ phần tử này v
Trang 1Võ Quang Hoàng Khang
Email: vqhkhang@gmail.com
1
CHƯƠNG 2.( TT ) GIẢI THUẬT SẮP XẾP
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 3Khái niệm
Sắp xếp là quá trình xử lý một danh sách các phần tử
để đặt chúng theo một thứ tự thỏa mãn một tiêu chí 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ừ đầudãy, tìm tất cả nghịch thế chứa phần tử này, triệttiê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 132
15
1
Trang 141
Kết thúc bước 1
Trang 151
10
7
Trang 16j
Trang 179
Trang 18j
Trang 1915
Trang 20j
Trang 2115 1
j
1
Kết thúc bước 2
2
Trang 2215 1
j
10
7
Trang 23Bước 3: Xét phần tử thứ ba (tại vị trí 3)
Trang 2415 1
j
Bước 3: Xét phần tử thứ ba (tại vị trí 3)
5 7
Trang 2615 1
j
Bước 3: Xét phần tử thứ ba (tại vị trí 3)
Trang 27Bước 3: Xét phần tử thứ ba (tại vị trí 3)
Kết thúc bước 3
3
Trang 2815 1
Trang 2915 1
j
Bước 4: Xét phần tử thứ tư (tại vị trí 4)
Trang 31Bước 4: Xét phần tử thứ tư (tại vị trí 4)
Trang 325
Trang 3315 1
Trang 342 1
Trang 3515 1
j
Bước 5: Xét phần tử thứ năm (tại vị trí 5)
7 9
Trang 36Kết thúc bước 5
Bước 5: Xét phần tử thứ năm (tại vị trí 5)
7
Trang 3815 1
j
Bước 6: Xét phần tử thứ sáu (tại vị trí 6)
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 44void Hoanvi(int &a, int &b)
Trang 45 Ðá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àokết quả so sánh, có thể ước lượng trong từngtrường hợp như sau:
45
Trang 46Bài tập
Minh họa từng bước thực hiện của giải thuậtInterchange Sort khi sắp dãy số sau tăngdần:
Cho biết tổng số phép hoán vị
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ệnhà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ệnhành chỉ còn 1 phần tử
47
Trang 48Chọn trực tiếp – selection sort
Trang 49Giả sử cần tìm vị trí phần tử nhỏ nhất trong dãy
số sau ?
Trang 50Bước 1: Giả sử vị trí phần tử nhỏ nhất là 1(vtmin), phần tử này có giá trị 10
vtmin
Trang 51Bước 2: So sánh giá trị tại vtmin với tất cả giá trịtại vị trí còn lại (từ 2 đến 8), nếu có phần tử nàonhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin
vtmin
5 nhỏ hơn 10 nên cập nhật
vị trí min
10
Trang 52Bước 2: So sánh giá trị tại vtmin với tất cả giá trịtại vị trí còn lại (từ 2 đến 8), nếu có phần tử nàonhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin
vtmin
7 lớn hơn 5 nên không cập nhật vị trí min
10
Trang 53Bước 2: So sánh giá trị tại vtmin với tất cả giá trịtại vị trí còn lại (từ 2 đến 8), nếu có phần tử nàonhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin
vtmin
3 nhỏ hơn 5 nên cập nhật
vị trí min
10
Trang 54Bước 2: So sánh giá trị tại vtmin với tất cả giá trịtại vị trí còn lại (từ 2 đến 8), nếu có phần tử nàonhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin
vtmin
9 lớn hơn 3 nên không cập nhật vị trí min
10
Trang 55Bước 2: So sánh giá trị tại vtmin với tất cả giá trịtại vị trí còn lại (từ 2 đến 8), nếu có phần tử nàonhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin
vtmin
1 nhỏ hơn 3 nên cập nhật
vị trí min
10
1
Trang 5615 lớn hơn 1 nên không cập nhật vị trí min
10
15 1
Trang 572 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í 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ấtbắ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 6969
Trang 70if (a[j ] < a[vtmin])
vtmin=j;
} Hoanvi(a[vtmin], a[i]);
}
Tìm vị trí min tính từ i đến N
Trang 71Ðánh giá giải thuật
Ðối với giải thuật chọn trực tiếp, có thể thấyrằ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ệnhà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, dovậy trong mọi trường hợp có thể kết luận :
71
Trang 73KIỂM TRA
Minh họa từng bước thực hiện khi sắp dãy số sau tăng dần:
- Đổi chỗ trực tiếp Cho biết tổng số phép hoán vị
- Chọn trực tiếp Cho biết tổng số phép gán tìm min
và tổng số phép hoán vị
73
Trang 74Chè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
74
Trang 821
Trang 831
Trang 84Chèn trực tiếp – insertion sort
84
Dựa vào đâu để xác định được vịtrí chèn thích hợp của một giá trịtrong dãy có giá trị tăng dần?
?
Trang 85Bướ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.
85
Trang 86void ChenTrucTiep(int a[], int N )
a[pos+1] = a[pos];
pos ;
}a[pos+1] = x;// chèn x vào dãy}
Trang 87 Đá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:
87
Trang 89Nổ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ặpphầ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.Lặp lại xử lý trên cho đến khi không còn cặpphần tử nào để xét
89
Trang 901 2 3 4 5 6 7
8
90
7 3 9 2 15 1
10 5 i
j
Trang 911 2 3 4 5 6 7
8
91
7 3 9 2 15
1 10 5 i
j
Trang 921 2 3 4 5 6 7
8
92
7 3 9 2
15
1
10 5 i
j
Trang 931 2 3 4 5 6 7
8
93
7 3
9 2
15
1
10 5 i
j
Trang 941 2 3 4 5 6 7
8
94
7 3
9 2
15
1
10
5 i
j
Trang 951 2 3 4 5 6 7
8
95
7 3
9 2
15
1
10
5 i
j
Trang 961 2 3 4 5 6 7
8
96
7 3
9 2
Trang 971 2 3 4 5 6 7
8
97
7 3
9 2
Trang 98Trong khi (j > i) thực hiện:
Nếu a[j]<a[j-1]: Hoán vị a[j] và a[j-1]
j = j-1;
Bước 3:
i = i+1;
Nếu i >N-1: Hết dãy Dừng Ngược lại: Lặp lại Bước 2
98
Trang 100Đánh giá giải thuật
Trong mọi trường hợp, số phép so sánh là:
Trang 101“Chèn trực tiếp” và “Chọn trực tiếp” đều có chiphí 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 choviệc sắp xếp các mảng lớn
101
Trang 103L=1 R=3
L=4 R=8 Đoạn 1 Đoạn 2
7 3 9 2 15 1
10 5
Trang 104L=5 R=8
Đoạn 1 Đoạn 2
3 7 9 5 15 10
1 2
Trang 1053 5 9 7 15 10
1 2
Trang 1063 5 7 9 15 10
1 2
Trang 1071 2 3 4 5 6 7 8
107
Đoạn cần sắp xếp
i j i=6, j=7 x
Trang 1081 2 3 4 5 6 7 8
108
Đoạn cần sắp xếp
i j i=4, j=5 x
Trang 1101 2 3 4 5 6 7 8
110
Đoạn cần sắp xếp
i j i=3, j=4 x
Trang 111Kết thúc
Trang 112 Nếu (L<j) Phân hoạch dãy aL … aj
Nếu (i<R) Phân hoạch dãy ai … aR
112
Trang 113Giải thuật phân hoạch dãy a L , a L+1 , … a R thành 2 dãy con
Bước 2b: Trong khi (a[j]>x)
j Bước 2c: Nếu (i≤j) Hoán vị a[i] và a[j]
Bước 3:
Nếu i<j: Lặp lại bước 2
Ngược lại: Dừng phân hoạch
113
Trang 114HoanVi(a[i], a[j]);
i++;
j ;
} } while(i<j);
Trang 115Đá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ớnnhất) O(n2)
115