Menu
CoddyTech

Selection sort (sắp xếp chọn)

Cập nhật lần cuối

Selection sort (sắp xếp chọn) chia mảng thành vùng đã sắp xếp ở bên trái và vùng chưa sắp xếp ở bên phải. Ở mỗi lượt, thuật toán quét vùng chưa sắp xếp để tìm phần tử nhỏ nhất, rồi đổi nó vào vị trí chưa sắp xếp đầu tiên, nhờ đó vùng đã sắp xếp lớn thêm một ô. Nhấn Phát ở trên để xem quá trình quét và đổi chỗ, hoặc chạy từng bước qua từng lần so sánh.

Selection sort luôn thực hiện cùng một số lần so sánh bất kể dữ liệu đầu vào, nhưng chỉ đổi chỗ tối đa n-1 lần, ít hơn nhiều so với bubble sort, điều này có thể quan trọng khi thao tác ghi tốn kém.

Độ phức tạp thời gian và không gian

Trường hợpĐộ phức tạpGhi chú
Tốt nhấtO(n²)Vẫn phải so sánh dù đã sắp xếp
Trung bìnhO(n²)Thứ tự ngẫu nhiên
Xấu nhấtO(n²)Sắp xếp ngược
Không gianO(1)Sắp xếp tại chỗ
Ổn địnhKhôngĐổi chỗ có thể đảo thứ tự các phần tử bằng nhau

Từng bước

BướcĐiều gì xảy ra
1Coi cả mảng là chưa sắp xếp.
2Quét vùng chưa sắp xếp để tìm phần tử nhỏ nhất.
3Đổi phần tử nhỏ nhất đó vào vị trí chưa sắp xếp đầu tiên.
4Dịch ranh giới sang phải một bước (ô đó giờ đã được sắp xếp).
5Lặp lại cho đến khi chỉ còn một phần tử chưa sắp xếp.

Ví dụ minh họa

Sắp xếp [5, 2, 4, 1]:

LượtMảngThao tác
Bắt đầu[5, 2, 4, 1]Cả mảng chưa được sắp xếp.
1[1, 2, 4, 5]Quét [5, 2, 4, 1], nhỏ nhất là 1 ở chỉ số 3; đổi nó với chỉ số 0.
2[1, 2, 4, 5]Quét [2, 4, 5], nhỏ nhất là 2, đã ở chỉ số 1; đổi với chính nó.
3[1, 2, 4, 5]Quét [4, 5], nhỏ nhất là 4, đã ở chỉ số 2; không cần di chuyển.
Xong[1, 2, 4, 5]Chỉ còn 5, nên nó đã ở đúng chỗ.

Khi nào nên dùng selection sort

Nên dùng khiTránh dùng khi
Thao tác ghi tốn kém: thuật toán đổi chỗ tối đa n-1 lần.Mảng lớn: O(n²) lần so sánh chiếm phần lớn thời gian.
Bạn cần một thuật toán sắp xếp tại chỗ đơn giản, dễ cài đặt.Bạn cần sắp xếp ổn định, giữ nguyên thứ tự các khóa bằng nhau.
Bộ nhớ hạn hẹp: thuật toán chỉ dùng thêm O(1) bộ nhớ.Dữ liệu gần như đã sắp xếp: nó không thể kết thúc sớm như insertion sort.
Tập dữ liệu rất nhỏ và hiệu năng dễ đoán là điều quan trọng.Thông lượng quan trọng: các thuật toán O(n log n) như quicksort nhanh hơn nhiều.

Code Selection Sort

Một cách cài đặt Selection Sort gọn gàng, chạy được ngay bằng Python, JavaScript, Java, C++, C, Pseudocode. Chọn một ngôn ngữ, sao chép code hoặc mở sẵn trong Coddy Playground.

Code Selection Sort bằng Python

Python
1def selection_sort(a):2    n = len(a)3    for i in range(n - 1):4        # Find the smallest element in the unsorted tail5        min_idx = i6        for j in range(i + 1, n):7            if a[j] < a[min_idx]:8                min_idx = j9        a[i], a[min_idx] = a[min_idx], a[i]10    return a11
12
13nums = [64, 25, 12, 22, 11]14print("Before:", nums)15selection_sort(nums)16print("After: ", nums)
Chạy code này trong Playground Python

Câu hỏi thường gặp về selection sort

Độ phức tạp thời gian của selection sort là bao nhiêu?
Selection sort tốn O(n²) trong mọi trường hợp, tốt nhất, trung bình và xấu nhất, vì nó luôn quét toàn bộ vùng chưa sắp xếp để tìm mỗi phần tử nhỏ nhất. Thuật toán dùng thêm O(1) bộ nhớ.
Selection sort có ổn định không?

Phiên bản tại chỗ tiêu chuẩn không ổn định, vì đổi một phần tử nhỏ nhất ở xa vào vị trí có thể đẩy một phần tử bằng nó vượt qua phần tử khác. Có biến thể ổn định nhưng phải dời phần tử thay vì đổi chỗ.

Khi nào selection sort hữu ích?
Thuật toán hữu ích khi chi phí ghi vào bộ nhớ cao, vì nó đổi chỗ tối đa n-1 lần, mức thấp nhất có thể với một thuật toán sắp xếp so sánh có di chuyển phần tử.
Selection sort khác bubble sort như thế nào?
Cả hai đều là thuật toán sắp xếp so sánh O(n²), nhưng selection sort đổi chỗ tối đa n-1 lần còn bubble sort có thể đổi chỗ tới O(n²) lần. Bubble sort còn phát hiện được mảng đã sắp xếp và dừng sớm, trong khi selection sort luôn chạy đủ số lượt.
Nên dùng selection sort hay insertion sort?
Trong hầu hết trường hợp, hãy chọn insertion sort: nó ổn định, chạy trong O(n) với dữ liệu gần như đã sắp xếp và trung bình nhanh hơn. Chỉ chọn selection sort khi ưu tiên hàng đầu là giảm số lần ghi, vì nó bảo đảm đổi chỗ tối đa n-1 lần.
Tại sao selection sort luôn chạy O(n²) kể cả với mảng đã sắp xếp?
Selection sort không có cách nào biết một phần tử đã là nhỏ nhất nếu không quét phần còn lại của vùng chưa sắp xếp, nên nó thực hiện mọi phép so sánh ở mọi lượt bất kể thứ tự đầu vào. Vì vậy trường hợp tốt nhất bằng trường hợp xấu nhất, đều là O(n²), khác với insertion sort hay bubble sort vốn có thể dừng sớm.
Hình minh họa các ngôn ngữ lập trình của Coddy

Thành thạo thuật toán cùng Coddy

Bắt đầu