c. Cài đặt
3.2.2. Phƣơng pháp chọn trực tiếp (Selection Sort)
a. Ý tƣởng giải thuật
Trong số n phần tử của danh sách, chọn phần tử nhỏ nhất, và đặt ở vị trí đầu tiên. Tiếp theo, trong số n-1 phần tử còn lại, chọn phần tử nhỏ nhất, và đặt ở vị trí thứ hai. Tƣơng tự, lặp lại quá trình này cho đến khi dãy cần duyệt chỉ còn một phần tử.
Các bƣớc thực hiện nhƣ sau:
Bƣớc 1: Gán i = 1;
Bƣớc 2: Tìm vị trí minPos của phần tử nhỏ nhất trong dãy từ A[i] đến A[n]
Gán minPos=i, j=i+1;
Bắt đầu lặp: Trong khi mà j<n
- Nếu A[j]<a[minPos] thì Gán minPos=j; - Tăng j: j=j+1;
Hết vòng lặp.
Bƣớc 3: Nếu minPos ≠ i thì: Hoán vị A[minPos] và a[i]
Bƣớc 4: Nếu i<n-1 thì
+ Tăng i: i = i+1; + Lặp lại bƣớc 2
Ngƣợc lại: DỪNG
b. Ví dụ minh họa
6 9 1 3 7 15 2
i=1
Hoán vị(A[1], A[3]) minPos=3
1 2 3 6 7 9 15
1 9 6 3 7 15 2
i=2
Hoán vị(A[2], A[7]) minPos=7
1 2 6 3 7 15 9
i=3
Hoán vị(A[3], A[4]) minPos=4
1 2 3 6 7 15 9 Không hoán vị
i=4 minPos=4
1 2 3 6 7 15 9 Không hoán vị
i=5 minPos=5
1 2 3 6 7 15 9 Hoán vị (A[6], A[7])
i=6 minPos=7
c. Cài đặt
Dƣới đây là hàm cài đặt của thuật toán. void SelectionSort(int A[], int n)
{ int minPos; for(int i=0;i<n-1;i++) { //Tìm vị trí phần tử nhỏ nhất minPos=i;
for(int j=i+1;j<n;j++)
if(A[j]<A[minPos]) minPos=j; //Hoán vị A[i], A[minIndex] if(minPos!=i) { int temp=a[i]; a[i]=a[minPos]; a[minPos]=temp; } } }
Đánh giá giải thuật
Sau mỗi bƣớc lặp theo i, cần tối đa 1 phép hoán vị để đƣa phần tử nhỏ nhất về đầu dãy đang xét. Nhƣ vậy, một danh sách n phần tử, cần nhiều nhất n-1 phép hoán vị. Điều này cho thấy thuật toán chọn trực tiếp về mặt lý thuyết có số phép hoán vị nhỏ hơn hoặc bằng thuât toán đổi chỗ trực tiếp. Bởi vì, trong thuật toán này, sau mỗi bƣớc lặp theo i, có thể cần nhiều hơn 1 phép hoán vị để có thể đƣa phần tử nhỏ nhất trong dãy đang xét về vị trí đầu (độc giả tự kiểm tra điều này, xem nhƣ là bài tập).
Xét số phép so sánh, hoàn toàn tƣơng tự cách tính trong thuật toán đổi chỗ trực tiếp, ta có tổng số phép so sánh là . Độ phức tạp của giải thuật là O(n2).