N IW E R S Y T E T K O N O M IC Z N Y W R A K O W IE Kolejki
Transkrypt
N IW E R S Y T E T K O N O M IC Z N Y W R A K O W IE Kolejki
Kolejki Kolejki Kolejka (ang. queue) - struktura danych umożliwiająca dodawanie obiektów, na jej końcu (ang. enqueue), oraz usuwanie/obsługę obiektów na jej początku (ang. dequeue). Kolejka znaczeniowo odpowiada swojej nazwie (np. kolejka do okienka w kinowej kasie). Przetwarzanie danych odbywa się zatem z zasadą pierwszy wchodzi, pierwszy wychodzi (ang. FIFO - First In First Out). Przykładowa kolejka UNIWERSYTET EKONOMICZNY W KRAKOWIE Rozpatrzmy przykład kolejki liczb całkowitych. Dostęp do tej struktury jest możliwy w dwóch miejscach, na jej początku (usuwanie danych) oraz końcu (dodawaie danych). początek koniec 34 65 148 59 12 obiekty dodawane są na końcu kolejki, a usuwane na początku 65 148 59 12 kolejka po operacji usun 65 148 59 12 47 kolejka po operacji dodaj(47) Nowy element może zostać dołączony tylko na końcu kolejki, a usunięty tylko z jej początku. Interfejs kolejki Podstawowe operacje związane z kolejką to: inicjalizacja kolejki, dodanie obiektu do kolejki, usunięcie obiektu z kolejki. Dodatkowe operacje które można wykonać na kolejce to między innymi: sprawdzenie czy kolejka jest pełna, sprawdzenie czy kolejka jest pusta, podgląd obiektu znajdującego się na początku kolejki, wyświetlenie zawartości kolejki, sprawdzenie liczby obiektów w kolejce. 23 Algorytmy i Struktury Danych Poniżej prosty interfejs kolejki liczb całkowitych. UNIWERSYTET EKONOMICZNY W KRAKOWIE interface KolejkaInterfejs { public void dodaj(int e); // dodaje element do kolejki (na jej końcu) public int usun(); // zwraca usunięty element z kolejki (z jej początku) public boolean czyPelna(); // sprawdza czy kolejka jest pełna public boolean czyPusta(); // sprawdza czy kolejka jest pusta public int zobacz(); // zwraca liczbę znajdującą się na początku kolejki // (nie usuwa jej) public void wyswietl(); // wyświetla zawartość kolejki (elementy w kolejce) public int rozmiar(); // zwraca rozmiar kolejki (liczbę jej elementów) } Implementacja kolejki Kolejkę w Javie, podobnie jak stos, można zaimplementować wykorzystując tablicę, albo listę powiązaną (struktura w pełni dynamiczna). Rozwiązanie tablicowe jest ograniczone maksymalnym rozmiarem założonej tablicy. Poniżej przykład kolejki łańcuchów tekstowych z wykorzystaniem wektora 10 elementowego. 9 8 7 Monika 6 Kasia 5 Robert 4 Iwona 3 Marek 2 Andrzej koniec początek 1 0 Powyższy przykład operuje dwoma zmiennymi, początek i koniec, które przechowują indeksy pierwszego i ostatniego elementu kolejki. Dodawanie i usuwanie elementów działa bardzo szybko, ale sama kolejka nie jest optymalna (po kilu operacjach osiągniemy maksymalny rozmiar tablicy, nie wykorzystując jej w pełni). Można po każdej operacji usuwania dokonać przemieszczenia elementów stanowiących kolejkę (początek byłby zawsze na indeksie zero - analogia do rzeczywistych kolejek, krok naprzód). Niestety to rozwiązanie, dla kolejek o dużej ilości elementów, jest mało efektywne (musimy kopiować znaczny obszar pamięci). Częściej wykorzystuje się kolejkę zawijaną, inaczej zwaną cykliczną. 24 UNIWERSYTET EKONOMICZNY W KRAKOWIE Kolejki 9 Monika 8 koniec 9 Monika 9 Monika Kasia 8 Kasia 8 Kasia 7 Robert 7 Robert 7 Robert 6 Iwona 6 Iwona 6 Iwona 5 Marek 5 Marek 5 Marek 4 Andrzej 4 Andrzej 4 Andrzej początek początek 3 3 3 2 2 2 1 1 1 Marta 0 0 0 Wojtek Wojtek koniec koniec++; //10 dodaj(“Wojtek”) koniec = 9 początek koniec koniec++; //11 dodaj(“Marta”) W kolejce cyklicznej zwiększamy wartość zmiennych początek (dodawanie elementów) i koniec (usuwanie elementów). Oczywiście musimi sprawdzać, czy kolejka nie jest przypadkiem pełna (wektor został całkowicie wykorzystany). Indeks tablicy, na którym wstawimy dodawany do kolejki element liczymy wykorzystując operator modulo (np. dla końca indeks = koniec % N; gdzie N jest rozmiarem tablicy). Zadania 1. Napisz klasę Kolejka będącą odzwierciedleniem kolejki dla liczb całkowitych. Klasa ma implementować interfejs KolejkaInterfejs oraz zawierać: // Pola private private private private int int int int [] tablica; poczatek; koniec; rozmiarKolejki; // // // // // wektor przechowujący elementy kolejki indeks elementu początkowego indeks elementu końcowego pole niewymagane (pomocnicze) przechowuje rozmiar kolejki (liczbę jej elementów) // Konstruktory public Kolejka() // domyślny konstruktor klasy (tworzy kolejkę o rozmiarze np. 10) public Kolejka(int rozmiar) // konstruktor umożliwiający podanie rozmiaru kolejki 25 Algorytmy i Struktury Danych Sprawdź działanie klasy poprzez: utworzenie kolejki, dodanie do kolejki liczb: 65, 12, 47, 31, 85, wyświetlenie zawartości kolejki i jej rozmiaru, usunięcie z kolejki jednej liczby, wyświetlenie zawartości kolejki, usunięcie z kolejki 2 liczb i dodanie czterech (42, 67, 28, 54), podgląd liczby znajdującej się na początku kolejki, wyświetlenie zawartości kolejki. 2. Napisz program, który rozwiązuje problem Józefa Flawiusza. W okręgu umieszczonych jest n obiektów (kolejne liczby całkowite), następnie eliminowany jest co k-ty obiekt, aż pozostanie tylko jeden. Program ma wypisać na ekranie, kolejność eliminowania obiektów. Wykorzystaj kolejkę. UNIWERSYTET EKONOMICZNY W KRAKOWIE Józef Flawiusz, w trakcie wojny rzymsko-żydowskiej został, wraz z grupą 40 żydowskich powstańców, otoczony przez Rzymian w jaskini. Powstańcy od pojmania woleli samobójstwo, dlatego też zdecydowali się utworzyć krąg i zabijać co trzecią osobę, aż zostanie tylko jedna, która popełni samobójstwo. Flawiusz chcąc uniknąć śmierci wyliczył, w którym miejscu powinien stanąć. Ustawił się na miejscu 16, dzięki czemu pozostał, jako przedostatnia osoba, przy życiu. Następnie, wraz z przyjacielem osobą z numerem 31, oddał się w ręce Rzymian i przeżył. 3. Napisz aplikację symulującą kolejki do kas w supermarkecie. Aplikacja powinna wyświetlać kilka kas oraz klientów, którzy stoją do aktualnej kasy. Dodanie klienta powinno się odbywać po naciśnięciu klawisza. Klient ma sam decydować do której kasy ma się ustawić (w zależności od rozmiaru kolejki). Czas obsługi kienta przez kasę powinien być uzależniony od ilości nabytych towarów. Upływ czasu zasymuluj naciśnięciem klawisza. Przykład: KASA 1: Adam [3], Marek [1], Jagoda[7] KASA 2: Roman [12], Ludwik [2], Kasia[6], Magda [1] KASA 3: Andrzej [3], Weronika [4] Wykorzystaj prostą klasę Klient (pola: np. ilość zakupionych towarów, imię itp.), a kilka stanowisk kasowych zapisz w odpowiednim wektorze. 26