materiał do pobrania

Transkrypt

materiał do pobrania
Klasyczne algorytmy działające na tablicach
Poznałeś już tablicę i podstawową obsługę zmiennych tego typu, pora więc przejść do realizacji
algorytmów, które działają na tablicach.
1. Przeszukiwanie liniowe tablicy jednowymiarowej
Przykład
Zajmijmy się problemem poszukiwania wyróżnionego elementu w jednowymiarowej tablicy.
Zakładamy przy tym, że element, którego szukamy, może się w tablicy znajdować lub nie.
W tym celu kolejno, począwszy od pierwszego elementu, będziemy sprawdzać, czy napotkana wartość
jest elementem szukanym. Nazwijmy go szuk. Jeśli już pierwszy element tablicy (oczywiście pierwszym elementem jest element indeksowany zerem!) okaże się poszukiwanym elementem, przeszukiwanie zakończymy, a
na wyjściu pojawi się informacja, że element szukany znajduje się w tablicy. W przeciwnym wypadku sprawdzamy, czy drugi element jest równy elementowi szukanemu, i tak postępujemy aż do ostatniego elementu
tablicy. Przeszukiwanie tablicy metodą element po elemencie nazywamy przeszukiwaniem liniowym. Po
każdym przebiegu pętli musimy oczywiście skontrolować, czy nie sprawdzamy ostatniego elementu tablicy, aby
nie wyjść poza zakres tablicy.
Specyfikacja problemu algorytmicznego i opis użytych zmiennych
Problem algorytmiczny:
Znalezienie wyróżnionego elementu w tablicy
Dane wejściowe:
Tablica tab [ n ], gdzie n to rozmiar tablicy,
szuk ∈ R - szukany element w tablicy tab
Dane wyjściowe:
Informacja o znalezieniu (bądź nie) elementu szuk
Zmienne pomocnicze:
i ∈ N ; i ∈{0,..., n − 1}
Zapiszmy algorytm w postaci listy kroków:
1. Wczytaj tablicę n-elementową, pobierz wartość elementu szukanego szuk.
2. Zmiennej pomocniczej i przypisz wartość 0.
3. Jeśli i jest mniejsze od n, przejdź do kroku 4, w przeciwnym wypadku wypisz „Element nie został
znaleziony" i zakończ.
4. Jeśli tab[i] jest różne od szuk, zwiększ o 1 wartość zmiennej i i przejdź do kroku 3.
5. Wypisz „Element został znaleziony" i zakończ.
Ryc. 5.7. Schemat blokowy wyszukiwania w tablicy wyróżnionego elementu
Porównaj schemat blokowy algorytmu (ryc. 5.7) z zapisem w postaci listy kroków, a następnie przeanalizuj
program:
Analiza złożoności obliczeniowej algorytmu przeszukiwania liniowego
Policzmy, ile w tym algorytmie wykonuje się operacji dominujących, czyli mających wpływ na
szybkość działania algorytmu. Załóżmy, że w tablicy nie ma szukanego elementu. Wówczas dla każdego
elementu tablicy wykonujemy dwa porównania: czy jego indeks świadczy o tym, że element mieści się w
zakresie tablicy, oraz czy element jest elementem szukanym. Przeanalizuj kod funkcji, która przeszukuje tablicę
w celu znalezienia elementu:
while
{
i++;
}
(i<10
&&
tablica[i]!=szukany)
A zatem dla n elementów wykonujemy w najgorszym wypadku 2n porównań. Złożoność obliczeniowa
tego algorytmu jest więc złożonością liniową. Liczbę porównań da się zmniejszyć dzięki zastosowaniu algorytmu przeszukiwania liniowego z wartownikiem.
2. Przeszukiwanie liniowe tablicy jednowymiarowej z wartownikiem
Podczas przeszukiwania tablicy w poprzednim przykładzie musieliśmy za każdym obiegiem pętli
wykonywać dwie czynności: porównywać kolejne elementy tablicy z wartością poszukiwaną i sprawdzać, czy
wartość indeksu tablicy nie przekracza dozwolonego zakresu. Poznasz teraz metodę przeszukiwania liniowego
tablicy z tak zwanym wartownikiem pozwalającą nam zrezygnować z „pilnowania" wyjścia poza zakres tablicy.
Dodajmy do tablicy dodatkowy element o poszukiwanej wartości i ustawmy go na końcu. Ten właśnie
element nazywamy wartownikiem. W tak zmodyfikowanej tablicy zawsze znajdziemy element szukany
(przecież sami wpisaliśmy go na końcu tablicy), mamy więc pewność, że algorytm skończy swoje działanie,
zanim wyjdzie poza zakres tablicy.
Aby móc wykorzystać metodę z wartownikiem, musisz użyć tablicy o liczbie elementów o jeden
większej niż liczba elementów do sprawdzenia. Dodatkowy element na końcu tablicy jest przeznaczony na
umieszczenie w nim wartownika.
Jeśli w przeszukiwanej tablicy nie ma szukanego elementu, to algorytm znajdzie ten ostatni,
dodatkowy. Dzięki takiemu rozwiązaniu algorytm nie musi za każdym razem sprawdzać, czy dotarł do końca
tablicy. Wystarczy, że po znalezieniu szukanego elementu sprawdza, czy jest on elementem dodatkowym (to
znaczy: czy ma indeks n). Jeśli tak, to wyprowadzony zostanie napis mówiący, że w tablicy nie ma szukanej
wartości (pamiętasz, że wartownik nie jest elementem badanej tablicy). W sytuacji pesymistycznej, gdy
elementu szukanego nie było w wejściowej tablicy, algorytm wykona n operacji porównań oraz jedno dodatkowe - sprawdzi, czy znaleziony element jest wartownikiem. Mimo że zmniejszyliśmy dwukrotnie liczbę operacji,
to klasa złożoności tego algorytmu się nie zmieniła i wynosi O(n), czyli jest liniowa - podobnie, jak w
przeszukiwaniu liniowym.
Na schemacie blokowym z ryciny 5.8 wyraźnie zauważalna jest mniejsza liczba dokonywanych
porównań niż w zapisie algorytmu w postaci listy kroków (specyfikacja jak w przykładzie wcześniejszym).
Ryc. 5.8. Schemat blokowy wyszukiwania z wartownikiem wyróżnionego elementu w tablicy
Lista kroków algorytmu:
1. Utwórz tablicę o rozmiarze o 1 większym niż wielkość badanej tablicy i wypełnij ją elementami
przeszukiwanej tablicy.
2. Wczytaj wartość elementu szukanego szuk.
3. Na końcu (po ostatnim elemencie) przeszukiwanej tablicy dopisz element o wartości szuk.
4. Zmiennej pomocniczej i (indeks tablicy) przypisz wartość 0.
5. 5. Jeśli tab[i] = szuk, przejdź do kroku 7.
6. Zwiększ zmienną i o 1 i przejdź do kroku 5.
7. Jeśli i < n, wypisz „Element został znaleziony" i zakończ.
8. Wypisz „Element nie został znaleziony" i zakończ.
Poniżej przedstawiamy samą funkcję przeszukującą tablicę z wartownikiem (reszta programu wyglądałaby
analogicznie jak w metodzie przeszukiwania liniowego, bez użycia wartownika):
void szukaj_z_wartownikiem(int tablica[11], int szukany)
{
int i;
tablica[10] = szukany;
i = 0;
while (tablica[i]!=szukany)
i++;
if (i<10)
cout << "Element zostal znaleziony";
else
cout << "Element nie zostal znaleziony";
}
Chociaż szukamy elementu w tablicy dziesięcioelementowej, w programie tworzymy tablicę
jedenastoelementową, gdyż pamiętamy, że ostatnim elementem jest wartownik niebędący elementem badanej
tablicy.