Strona główna » Algorytmy » Sortowanie » Sortowanie Cyklami
 

Sortowanie Cyklami

Opis

Algorytm Sortowania Cyklami to algorytm sortowania w miejscu w sposób niestabilny. Sortowanie odbywa się poprzez wybranie każdego kolejnego elementu, a następnie wstawienie go w odpowiednie miejsce, które możemy obliczyć wiedząc ile jest mniejszych elementów od niego. Zaletą tego algorytmu jest fakt, że każdy element jest nadpisywany maksymalnie raz, więc jest on przydatny wszędzie tam gdzie zapis jest kosztowny.

Lista kroków

Dla każdego kolejnego elementu wyliczamy ile jest na liście elementów mniejszych od niego. Jeśli wyliczona pozycja jest taka sama jak ta na której element się znajduje to nic nie robimy. W przeciwnym razie wstawiamy w odpowiednie miejsce, a dla nadpisanego elementu szukamy jego właściwej pozycji.

Przykład

Weźmy przykładowo tablice L := {5, 1, 4, 3, 2}. Wykonane zostaną kolejne kroki:

ListaWybranyKomentarz
{[5], 1, 4, 3, 2}5Wybieramy pierwszy element, 4 element są od niego mniejsze, więc trafia na pozycję 4
{[_], 1, 4, 3, 5}2Na pozycji 4 było 2, więc zliczamy dla niej liczbę elementów mniejszych i wstawiamy na pozycję 1
{[_], 2, 4, 3, 5}1Na pozycji 1 było 1, więc ponownie zliczamy mniejsze elementy i w wyniku otrzymujemy pozycję 0
{1, [_], 4, 3, 5}2Wybieramy kolejny element do sortowania, jest na swojej pozycji, więc nic nie robimy
{1, 2, [_], 3, 5}4Wybieramy kolejny element, mniejszych od niego są 3 elemeny, więc zmieniamy jego pozycję
{1, 2, [_], 4, 5}3Dla zastąpionego elementu zliczamy ile jest mniejszych od niego i wstawiamy na pozycję 2
{1, 2, 3, [4], 5}4Wybieramy kolejny element do sortowania, jest na swojej pozycji, więc nic nie robimy
{1, 2, 3, 4, [5]}5Wybieramy kolejny element do sortowania, jest na swojej pozycji, więc nic nie robimy
{1, 2, 3, 4, 5}-Tablica została posortowana

Złożoność

Zauważmy, że niezależnie od tego jak wygląda lista to dla każdego z n elementów wykonujemy dokładnie n - 1 porównań, więc zawsze gwarantowane jest, że operacji będzie n2 z czego wynika złożoność O(n2). Dodatkowo warto zauważyć, że algorytm wymaga jedynie zapamiętania poza tablicą pojedynczego elementu, więc złożoność pamięciowa wynosi O(1). Warto oczywiście dodatkowo pamiętać, że każdy element może zostać napisany maksymalnie raz, więc maksymalna ilość zapisów wynosi n. Większość algorytmów poprzez stosowanie zamian elementów potrzebuje o wiele więcej zamian.

Implementacja

Funkcja sortuj() sortuje podane dane w tablicy w miejscu zgodnie z algorytmem Sortowania Cyklami.

C++
C#
  1. static void sortuj(int[] tab) {
  2.   for (int i = 0; i < tab.Length - 1; i++) {
  3.     int item = tab[i];
  4.     int pos = i;
  5.     for (int j = i + 1; j < tab.Length; j++)
  6.       if (tab[j] < item)
  7.         pos++;
  8.     if (pos == i)
  9.       continue;
  10.     while (item == tab[pos])
  11.       pos++;
  12.     swap(ref tab[pos], ref item);
  13.     while (pos != i) {
  14.       pos = i;
  15.       for (int j = i + 1; j < tab.Length; j++)
  16.         if (tab[j] < item)
  17.           pos++;
  18.       while (item == tab[pos])
  19.         pos++;
  20.       swap(ref tab[pos], ref item);
  21.     }
  22.   }
  23. }

(2.) Dla każdego elementu w tablicy (prócz ostatniego, bo nie ma takiej potrzeby): (3.) zapamiętujemy element, (4.) przyjmujemy, że jest na prawidłowej pozycji. Dalej (5. - 7.) weryfikujemy to poprzez aktualizację jego pozycji. (8.) Jeśli mimo wszystko jest na swojej pozycji to (9.) przechodzimy do następnej iteracji, ale jeśli nie to musimy ten element przestawić. W celu wstawienia (10. - 11.) sprawdzamy czy na miejscu do wstawienia nie ma już danego elementu - jeśli jest to zwiększamy numer pozycji, a potem (12.) zamieniamy przestawiany element z elementem na danej pozycji. Potem (13. - 21.) powtarzamy proces wstawiania dla każdego kolejnego elementu, aż nie wrócimy pod indeks z którego rozpoczął się cykl zamiany.

Testowanie funkcji

Poniższy fragment kodu wczytuje od użytkownika długość tablicy oraz jej elementy, a następnie ją sortuje i wypisuje na ekran.

C++
C#
  1. static void Main(string[] args) {
  2.   Console.Write("Podaj ile jest elementow\n n = ");
  3.   int n = Convert.ToInt32(Console.ReadLine());
  4.   int[] tab = new int[n];
  5.   Console.WriteLine("Podaj elementy:");
  6.   for (int i = 0; i < n; i++)
  7.     tab[i] = Convert.ToInt32(Console.ReadLine());
  8.   sortuj(tab);
  9.   Console.WriteLine("Po posortowaniu:");
  10.   for (int i = 0; i < n; i++)
  11.     Console.Write("{0} ", tab[i]);
  12.   Console.ReadKey();
  13. }

Zadania

Zadanie 1

Sprawdź dla wszystkich permutacji ciągu o długości n ile jest potrzebnych operacji nadpisania elementów w tablicy na przykładzie Sortowania Cyklami oraz Sortowania Przez Wybór. Przetestuj działanie funkcji na wybranych danych. Pamiętaj, że zliczane mają być wszystkie zapisy do tablicy!

Przykładowo dla permutacji 5 elementów program (w zależności od implementacji algorytmów) może wypisać:

  1. Sortowanie     Zapisow
  2. Cyklami        480
  3. Przez Wybór    652