RKRNAOSZ4SAMD
Zdjęcie przedstawia owoce sezonowe w małych pojemnikach, porzeczki, jagody, borówki, maliny i poziomki.

I_P_W14_M09_C++ Metody sortowania

Źródło: Alex Block, domena publiczna.

Wyszukiwanie elementu w zbiorze posortowanym i nieposortowanym

Zaprezentujmy na przykładzie, jak ważne jest sortowanie elementów i jak bardzo może usprawnić pracę programu. Porównajmy liczbę operacji, jakie będą musiały zostać wykonane podczas wyszukiwania elementu w zbiorze zarówno posortowanym, jak i nieposortowanym.

Specyfikacja problemu:

Dane:

  • tab – przeszukiwana tablica liczb

  • szukana_liczba – liczba której szukamy

Wynik:

  • informacja, czy szukana_liczba znajduje się w tablicy tab

By porównać przykładową liczbę operacji, działanie programu przetestujemy dla tablicy, w skład której wchodzą następujące liczby: 30, 3, 20, 28, 21, 18, 5, 6, 1, 14.

Będziemy szukać liczby 18.

Wyszukiwanie liniowe – wyszukiwanie w zbiorze nieposortowanym.  Ten algorytm realizowany jest liniowo – element po elemencie. Algorytm będzie prezentował się w następujący sposób:

Linia 1. funkcja wyszukiwanie podkreślnik liniowe otwórz nawias okrągły tab przecinek szukana podkreślnik liczba zamknij nawias okrągły. Linia 2. znaleziono ← fałsz. Linia 3. i ← 0. Linia 4. dopóki znaleziono wykrzyknik znak równości prawda oraz i otwórz nawias ostrokątny długość otwórz nawias okrągły tab zamknij nawias okrągły wykonuj dwukropek. Linia 5. j. Linia 8. jeśli znaleziono znak równości fałsz. Linia 9. wypisz cudzysłów Nie znaleziono szukanej liczby cudzysłów.

Przebieg algorytmu dla podanych danych:

  • Inicjalizujemy zmienne.

  • Rozpoczynamy pętlę:

    • tab[0] = 30 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 1 porównanie.

    • tab[1] = 3 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 2 porównania.

    • tab[2] = 20 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 3 porównania

    • tab[5] = 18 - jest to szukana liczba. Wypisujemy Znaleziono liczbę na pozycji: 5. Ustawiamy znaleziono <-- prawda. Wykonaliśmy 6 porównań. Kończymy działanie algorytmu.

Podsumowując, wykonaliśmy 6 porównań wewnątrz pętli i żadnego porównania po pętli.

Wyszukiwanie liniowe z wartownikiem – na końcu przeszukiwanego zbioru dodajemy element równy poszukiwanemu.

Algorytm będzie prezentował się w następujący sposób:

Linia 1. funkcja wyszukiwanie podkreślnik liniowe podkreślnik wartownik otwórz nawias okrągły tab przecinek szukana podkreślnik liczba zamknij nawias okrągły. Linia 2. tab otwórz nawias kwadratowy długość otwórz nawias okrągły tab zamknij nawias okrągły zamknij nawias kwadratowy ← szukana podkreślnik liczba. Linia 3. i ← 0. Linia 5. dopóki tab otwórz nawias kwadratowy i zamknij nawias kwadratowy wykrzyknik znak równości szukana podkreślnik liczba wykonuj dwukropek. Linia 6. i ← i plus 1. Linia 8. jeśli i otwórz nawias ostrokątny długość otwórz nawias okrągły tab zamknij nawias okrągły minus 1 dwukropek. Linia 9. wypisz cudzysłów Znaleziono liczbę na pozycji dwukropek cudzysłów i. Linia 10. w przeciwnym przypadku dwukropek. Linia 11. wypisz cudzysłów Nie znaleziono szukanej liczby cudzysłów.

Przebieg algorytmu dla podanych danych:

  • Inicjalizujemy zmienne (pamiętamy o dodaniu wartownika).

  • Rozpoczynamy pętlę:

    • tab[0] = 30 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 1 porównanie.

    • tab[1] = 3 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 2 porównania.

    • tab[2] = 20 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 3 porównania.

    • tab[3] = 28 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 4 porównania.

    • tab[4] = 21 - nie jest to szukana liczba, zwiększamy i o 1. Wykonaliśmy 5 porównania.

    • tab[5] = 18 - jest to szukana liczba. Wykonaliśmy 6 porównań.

  • Po wyjściu z pętli:

    • sprawdzamy warunek i < długość(tab) - 1:

      • i = 5

      • długość(tab) - 1 = 10 (ponieważ długość tablicy wynosi 11 po dodaniu wartownika)

      • Ponieważ 5 < 10, więc wypisujemy Znaleziono liczbę na pozycji: 5.

Podsumowując, wykonaliśmy 6 porównań wewnątrz pętli i 1 porównanie po pętli (porównanie wartości i z wartością długość(tab) - 1).

Wyszukiwanie binarne – wyszukiwanie w zbiorze posortowanym. Pierwszym krokiem, jaki musimy wykonać, jest posortowanie zbioru. Jest to wymóg zastosowania wyszukiwania binarnego.

Posortowany zbiór będzie wyglądał następująco: {1, 3, 5, 6, 14, 18, 20, 21, 28, 30}.

Następnie wykonujemy algorytm wyszukiwania binarnego:

Linia 1. funkcja wyszukiwanie podkreślnik binarne otwórz nawias okrągły tab przecinek szukana podkreślnik liczba zamknij nawias okrągły. Linia 2. lewo ← 0. Linia 3. prawo ← długość otwórz nawias okrągły tab zamknij nawias okrągły minus 1. Linia 5. dopóki lewo otwórz nawias ostrokątny znak równości prawo wykonuj dwukropek. Linia 6. i ← otwórz nawias okrągły prawo plus lewo zamknij nawias okrągły prawy ukośnik prawy ukośnik 2. Linia 7. jeżeli tab otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias ostrokątny szukana podkreślnik liczba. Linia 8. lewo ← i plus 1. Linia 9. w innym przypadku. Linia 10. jeżeli tab otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias ostrokątny szukana podkreślnik liczba. Linia 11. prawo otwórz nawias ostrokątny minus i minus 1. Linia 12. w innym przypadku. Linia 13. wypisz cudzysłów Znaleziono liczbę na pozycji dwukropek cudzysłów i. Linia 15. jeżeli lewo zamknij nawias ostrokątny prawo dwukropek. Linia 16. wypisz cudzysłów Nie znaleziono liczby cudzysłów.

Przebieg algorytmu dla podanych danych:

  • Inicjalizujemy zmienne (pamiętamy o dodaniu wartownika).

  • Rozpoczynamy pętlę:

    • i <-- (9 + 0) // 2 to 4,czyli tab[4] = 14.

      • 14 < 18 zatem wykonujemy lewo <-- i + 1, co daje lewo <-- 5. Wykonaliśmy 1 porównanie.

    • i <-- (9 + 5) / 2 to 7. Czyli tab[7] = 21.

      • 21 < 18 zatem wykonujemy prawo <-- i - 1, co daje prawo <-- 6. Wykonaliśmy 2 porównania.

    • i <-- (6 + 5) // 2 to 5,czyli tab[5] = 18. Wypisujemy Znaleziono liczbę na pozycji: 5.

Podsumowując, wykonaliśmy 3 porównania (podziały) wewnątrz pętli.

Jak widzimy, algorytm wyszukiwania binarnego zadziałał szybciej niż algorytm liniowy.

Aby można było skorzystać z algorytmu wyszukiwania binarnego, zbiór danych musi być posortowany. W sytuacji, gdy zbiór, w którym jest niewiele elementów, nie będzie często przeszukiwany (np. chcemy wyłącznie raz sprawdzić, czy znajduje się w nim dany element), metoda liniowa (czyli taka, która nie wymaga od nas wcześniejszego posortowania zbioru) może okazać się w zupełności wystarczająca.

Warto jednak pamiętać, że utrzymywanie dużego posortowanego zbioru danych, w którym często szukamy informacji, jest znacznie korzystniejsze ze względu na czas, jaki zajmuje każde wyszukanie. Nawet jeżeli sam proces sortowania okaże się czasochłonny – wykonamy go tylko raz, za to zaoszczędzimy sporo czasu na wielokrotnym przeszukiwaniu zbioru. Dlatego też tak ważna jest znajomość i umiejętność skutecznego użycia podstawowych algorytmów sortowania.