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?
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.