Selection sort (sortowanie przez wybieranie)
Ostatnia aktualizacja
Sortowanie przez wybieranie dzieli tablicę na posortowaną część po lewej i nieposortowaną po prawej. W każdym przebiegu przegląda nieposortowaną część, aby znaleźć najmniejszy element, a potem zamienia go na pierwszą nieposortowaną pozycję, powiększając posortowaną część o jeden. Kliknij odtwarzanie powyżej i zobacz przeglądanie i zamiany albo przechodź przez nie po jednym porównaniu.
Sortowanie przez wybieranie zawsze wykonuje tyle samo porównań niezależnie od danych, ale najwyżej n-1 zamian, czyli znacznie mniej niż sortowanie bąbelkowe, co może mieć znaczenie, gdy zapisy są kosztowne.
Złożoność czasowa i pamięciowa
| Przypadek | Złożoność | Uwagi |
|---|---|---|
| Najlepszy przypadek | O(n²) | Porównania odbywają się nawet dla posortowanych danych |
| Średni przypadek | O(n²) | Losowa kolejność |
| Najgorszy przypadek | O(n²) | Posortowane odwrotnie |
| Pamięć | O(1) | W miejscu |
| Stabilne | Nie | Zamiany mogą zmienić kolejność równych elementów |
Krok po kroku
| Krok | Co się dzieje |
|---|---|
| 1 | Potraktuj całą tablicę jako nieposortowaną. |
| 2 | Przejrzyj nieposortowaną część, aby znaleźć najmniejszy element. |
| 3 | Zamień to minimum na pierwszą nieposortowaną pozycję. |
| 4 | Przesuń granicę o jeden krok w prawo (to pole jest już posortowane). |
| 5 | Powtarzaj, aż nieposortowany zostanie tylko jeden element. |
Przykład krok po kroku
Sortowanie [5, 2, 4, 1]:
| Przebieg | Tablica | Działanie |
|---|---|---|
| Start | [5, 2, 4, 1] | Cała tablica jest nieposortowana. |
| 1 | [1, 2, 4, 5] | Przejrzyj [5, 2, 4, 1], minimum to 1 pod indeksem 3; zamień je z indeksem 0. |
| 2 | [1, 2, 4, 5] | Przejrzyj [2, 4, 5], minimum to 2, już pod indeksem 1; zamiana z samym sobą. |
| 3 | [1, 2, 4, 5] | Przejrzyj [4, 5], minimum to 4, już pod indeksem 2; ruch niepotrzebny. |
| Koniec | [1, 2, 4, 5] | Zostało tylko 5, więc jest już na swoim miejscu. |
Kiedy używać sortowania przez wybieranie
| Używaj, gdy | Unikaj, gdy |
|---|---|
Zapisy są kosztowne: algorytm wykonuje najwyżej n-1 zamian. | Tablica jest duża: dominuje O(n²) porównań. |
| Potrzebujesz prostego, łatwego w implementacji sortowania w miejscu. | Potrzebujesz stabilnego sortowania, które zachowuje kolejność równych kluczy. |
Pamięci jest mało: zużywa tylko O(1) dodatkowej pamięci. | Dane są prawie posortowane: nie potrafi skończyć wcześniej jak sortowanie przez wstawianie. |
| Zbiór danych jest malutki i liczy się przewidywalna wydajność. | Liczy się przepustowość: sortowania O(n log n), takie jak quicksort, są znacznie szybsze. |
Selection Sort: kod
Przejrzysta, gotowa do uruchomienia implementacja algorytmu Selection Sort w językach: Python, JavaScript, Java, C++, C, Pseudocode. Wybierz język, skopiuj kod albo otwórz go od razu w edytorze online Coddy.
Selection Sort: kod (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)Selection Sort: kod (JavaScript)
1function selectionSort(a) {2 for (let i = 0; i < a.length - 1; i++) {3 let min = i;4 // Find the smallest element in the unsorted tail5 for (let j = i + 1; j < a.length; j++) {6 if (a[j] < a[min]) min = j;7 }8 if (min !== i) [a[i], a[min]] = [a[min], a[i]];9 }10 return a;11}12
13const data = [5, 2, 9, 1, 7, 3];14console.log("Before:", data);15console.log("Sorted:", selectionSort([...data]));Selection Sort: kod (Java)
1import java.util.Arrays;2
3public class Main {4 static void selectionSort(int[] arr) {5 for (int i = 0; i < arr.length - 1; i++) {6 int minIndex = i;7 // Find the smallest value in the unsorted part8 for (int j = i + 1; j < arr.length; j++) {9 if (arr[j] < arr[minIndex]) minIndex = j;10 }11 int tmp = arr[i];12 arr[i] = arr[minIndex];13 arr[minIndex] = tmp;14 }15 }16
17 public static void main(String[] args) {18 int[] arr = {29, 10, 14, 37, 13, 5};19 System.out.println("Before: " + Arrays.toString(arr));20 selectionSort(arr);21 System.out.println("After: " + Arrays.toString(arr));22 }23}Selection Sort: kod (C++)
1#include <iostream>2#include <utility>3#include <vector>4
5void printVec(const std::vector<int>& a) {6 for (int x : a) std::cout << x << " ";7 std::cout << "\n";8}9
10void selectionSort(std::vector<int>& a) {11 for (size_t i = 0; i + 1 < a.size(); ++i) {12 // Find the smallest element in the unsorted suffix13 size_t minIdx = i;14 for (size_t j = i + 1; j < a.size(); ++j) {15 if (a[j] < a[minIdx]) minIdx = j;16 }17 std::swap(a[i], a[minIdx]);18 }19}20
21int main() {22 std::vector<int> data = {29, 10, 14, 37, 13, 5};23 std::cout << "Before: ";24 printVec(data);25 selectionSort(data);26 std::cout << "After: ";27 printVec(data);28 return 0;29}Selection Sort: kod (C)
1#include <stdio.h>2
3void printArr(const int a[], int n) {4 for (int i = 0; i < n; i++) printf("%d ", a[i]);5 printf("\n");6}7
8void selectionSort(int a[], int n) {9 for (int i = 0; i < n - 1; i++) {10 // Find the smallest element in the unsorted suffix11 int minIdx = i;12 for (int j = i + 1; j < n; j++) {13 if (a[j] < a[minIdx]) minIdx = j;14 }15 int tmp = a[i];16 a[i] = a[minIdx];17 a[minIdx] = tmp;18 }19}20
21int main(void) {22 int data[] = {29, 10, 14, 37, 13, 5};23 int n = sizeof(data) / sizeof(data[0]);24 printf("Before: ");25 printArr(data, n);26 selectionSort(data, n);27 printf("After: ");28 printArr(data, n);29 return 0;30}Selection Sort: kod (Pseudocode)
1DECLARE nums : ARRAY[1:7] OF INTEGER2DECLARE n : INTEGER3n ← 74nums[1] ← 75nums[2] ← 36nums[3] ← 97nums[4] ← 18nums[5] ← 59nums[6] ← 810nums[7] ← 211DECLARE i : INTEGER12DECLARE j : INTEGER13DECLARE minIndex : INTEGER14DECLARE temp : INTEGER15
16// Select the smallest remaining value and swap it into place17FOR i ← 1 TO n - 118 minIndex ← i19 FOR j ← i + 1 TO n20 IF nums[j] < nums[minIndex] THEN21 minIndex ← j22 ENDIF23 NEXT j24 IF minIndex <> i THEN25 temp ← nums[i]26 nums[i] ← nums[minIndex]27 nums[minIndex] ← temp28 ENDIF29NEXT i30
31FOR i ← 1 TO n32 OUTPUT nums[i]33NEXT iSelection sort: najczęstsze pytania
Jaka jest złożoność czasowa sortowania przez wybieranie?
O(n²) w każdym przypadku, najlepszym, średnim i najgorszym, bo zawsze przegląda całą nieposortowaną część, aby znaleźć każde minimum. Zużywa O(1) dodatkowej pamięci.Czy sortowanie przez wybieranie jest stabilne?
Standardowa wersja w miejscu nie jest stabilna, bo zamiana odległego minimum na jego miejsce może przenieść równy element za inny. Istnieje wariant stabilny, ale wymaga przesuwania zamiast zamieniania.
Kiedy sortowanie przez wybieranie jest przydatne?
n-1 zamian, czyli minimum możliwe dla sortowania przez porównania, które przenosi elementy.Czym różni się sortowanie przez wybieranie od sortowania bąbelkowego?
O(n²), ale sortowanie przez wybieranie wykonuje najwyżej n-1 zamian, a sortowanie bąbelkowe nawet O(n²) zamian. Sortowanie bąbelkowe potrafi też wykryć już posortowaną tablicę i zakończyć się wcześniej, a sortowanie przez wybieranie zawsze wykonuje pełną liczbę przebiegów.Sortowanie przez wybieranie czy przez wstawianie: co wybrać?
O(n) na prawie posortowanych danych i jest średnio szybsze. Sortowanie przez wybieranie wybierz tylko wtedy, gdy priorytetem jest minimalna liczba zapisów, bo gwarantuje najwyżej n-1 zamian.Dlaczego sortowanie przez wybieranie zawsze działa w O(n²), nawet na posortowanej tablicy?
O(n²), w przeciwieństwie do sortowania przez wstawianie czy bąbelkowego, które potrafią zakończyć się wcześniej.