Twoje Centrum Szkoleniowe

Nauczmy się dziś czegoś nowego!

Kurs programowania - C++

C++: Sortowanie przez wybieranie (Selection Sort)

Sortowanie przez wybieranie polega na wielokrotnym wyszukiwaniu najmniejszego (lub największego, w zależności od porządku sortowania) elementu w niesortowanej części tablicy i zamianie go z pierwszym elementem tej części. Proces ten jest powtarzany, aż cała tablica zostanie posortowana.

 

Główne cechy charakterystyczne tego algorytmu

  • Prostota: Algorytm jest łatwy do zrozumienia i implementacji, nawet dla początkujących programistów.
  • Niestabilność: Sortowanie przez wybieranie nie jest stabilne, co oznacza, że może zmieniać kolejność równych elementów.
  • In-place: Nie wymaga dodatkowej pamięci oprócz wejściowej tablicy, co czyni go algorytmem sortowania 'in-place'.
  • Ograniczona wydajność: Dla dużych zbiorów danych nie jest tak wydajny jak bardziej zaawansowane algorytmy.

 

Zasada działania sortowania przez wybieranie

 

Mechanizm wyboru minimalnego elementu z niesortowanej części tablicy

Podstawową ideą algorytmu jest przeszukanie niesortowanej części tablicy w celu znalezienia najmniejszego elementu. W każdej iteracji algorytm rozpoczyna od pierwszego elementu niesortowanej części tablicy i porównuje go z każdym kolejnym elementem, aby znaleźć najmniejszy. Ta metoda selektywnego wyszukiwania najmniejszego elementu jest powtarzana aż do posortowania całej tablicy.

 

Proces przesuwania tego elementu na początek niesortowanej sekcji

Po wybraniu najmniejszego elementu z niesortowanej części, algorytm wymienia go z elementem znajdującym się na początku tej części. W praktyce oznacza to, że najmniejszy element zostaje przesunięty na swoją ostateczną, posortowaną pozycję. Następnie, granica między sortowaną, a niesortowaną częścią tablicy przesuwa się o jeden element do przodu.

 

Wpływ metody na ogólną strukturę sortowanej tablicy

Charakterystyczną cechą sortowania przez wybieranie jest to, że tworzy ono na bieżąco "posortowaną" część tablicy na jednym końcu, podczas gdy drugi koniec pozostaje niesortowany. W miarę postępów algorytmu, posortowana sekcja rośnie, a niesortowana maleje. Interesującym aspektem tej metody jest fakt, że gdy tylko element zostanie umieszczony na właściwej pozycji w posortowanej sekcji, już nie jest poruszany.

 

Przykładowa implementacja w C++

 

Kroki implementacji algorytmu sortowania przez wybieranie w języku C++

  1. Inicjalizacja: Rozpocznij od zdefiniowania tablicy lub wektora, który będzie sortowany.

  2. Wyszukiwanie Miniumum: W każdej iteracji algorytmu wyszukaj najmniejszy element w niesortowanej części tablicy.

  3. Zamiana Elementów: Po znalezieniu najmniejszego elementu, zamień go z pierwszym elementem niesortowanej części tablicy.

  4. Aktualizacja Granicy: Po każdej iteracji przesuń granicę między sortowaną a niesortowaną częścią tablicy.

  5. Powtarzanie Procesu: Powtarzaj proces, aż cała tablica zostanie posortowana.

 

Przykład kodu ilustrującego algorytm

#include <iostream>
#include <vector>

void selectionSort(std::vector<int>& arr) {
    int n = arr.size();
    for (int i = 0; i < n-1; i++) {
        int min_index = i;
        for (int j = i+1; j < n; j++)
            if (arr[j] < arr[min_index])
                min_index = j;
        
        std::swap(arr[min_index], arr[i]);
    }
}

int main() {
    std::vector<int> data = {64, 25, 12, 22, 11};
    selectionSort(data);
    for (int i : data)
        std::cout << i << " ";
    return 0;
}

 

Analiza kodu

  • Funkcja selectionSort: Przyjmuje referencję do wektora arr, który ma zostać posortowany.

  • Zmienna min_index: Używana do przechowywania indeksu najmniejszego elementu w niesortowanej części tablicy.

  • Pętla Wewnętrzna: Szuka najmniejszego elementu w niesortowanej części tablicy.

  • Swap: Zamienia miejscami najmniejszy element z pierwszym elementem niesortowanej części.

  • Pętla Zewnętrzna: Powtarza proces dla każdego elementu tablicy.

 

Optymalizacje i warianty algorytmu: Sortowanie Przez Wybieranie

Sortowanie przez wybieranie (Selection Sort) jest prostym algorytmem, ale istnieją różne techniki i warianty, które mogą zwiększyć jego efektywność w określonych warunkach. Zrozumienie tych optymalizacji jest kluczowe dla programistów, aby móc lepiej dostosować algorytm do konkretnych wymagań i kontekstów.

 

Metody poprawy efektywności sortowania przez wybieranie

  1. Minimalizacja liczby operacji zamiany: Jedną z cech sortowania przez wybieranie jest fakt, że liczba zamian jest zminimalizowana. Można to dalej zoptymalizować, wykonując zamianę tylko wtedy, gdy faktycznie znajdziemy mniejszy element.

  2. Podwójne wyszukiwanie: W każdej iteracji można szukać zarówno najmniejszego, jak i największego elementu, co pozwala na zmniejszenie liczby potrzebnych iteracji o połowę. Jest to szczególnie efektywne w dużych zbiorach danych.

  3. Wykorzystanie struktur danych: Użycie odpowiednich struktur danych, takich jak kopce (heaps), może przyspieszyć proces znajdowania minimalnego lub maksymalnego elementu.

 

Analiza złożoności

 

Złożoność czasowa algorytmu

  1. Przypadek ogólny: Sortowanie przez wybieranie ma złożoność czasową O(n²), gdzie n to liczba elementów w tablicy. Jest to wynik dwóch zagnieżdżonych pętli: zewnętrznej, która przechodzi przez każdy element, i wewnętrznej, która szuka najmniejszego elementu w pozostałej części tablicy.

  2. Najlepszy przypadek: Nawet gdy tablica jest już posortowana, złożoność pozostaje O(n²) ze względu na konieczność przeszukania każdego elementu, aby upewnić się, że jest on najmniejszy.

  3. Najgorszy przypadek: Analogicznie, w najgorszym przypadku, gdy elementy są ułożone w odwrotnej kolejności, złożoność również wynosi O(n²).

 

Porównanie złożoności przestrzennej

Sortowanie przez wybieranie jest algorytmem sortowania "na miejscu", co oznacza, że nie wymaga dodatkowej przestrzeni pamięci poza danymi wejściowymi. Złożoność przestrzenna wynosi O(1), co czyni go bardziej przestrzennie wydajnym niż niektóre inne algorytmy, które wymagają dodatkowej pamięci, na przykład algorytmy sortowania przez scalanie.

 

Wpływ charakterystyki danych wejściowych

  1. Rozmiar danych: Sortowanie przez wybieranie staje się nieefektywne dla dużych zbiorów danych z powodu swojej kwadratowej złożoności czasowej.

  2. Rozkład danych: Algorytm nie jest wrażliwy na początkowy rozkład danych; jego wydajność nie zmienia się znacząco, niezależnie od tego, czy dane są częściowo posortowane, całkowicie losowe czy posortowane w odwrotnej kolejności.

 

 

Testy przypięte do lekcji
Aby uzyskać dostęp do testów i ćwiczeń interaktywnych - Zaloguj się
Aby widzieć ocenę lekcji - Zaloguj się