Laboratorium 5 –ADT kolejki priorytetowej i realizacja za pomocą
Transkrypt
Laboratorium 5 –ADT kolejki priorytetowej i realizacja za pomocą
Laboratorium 5 –ADT kolejki priorytetowej i realizacja za pomocą drzewa poszukiwań binarnych Cele: • Zastosowanie struktur wiązanych, zwanych również dynamicznymi lub rekurencyjnymi strukturami danych do realizacji kolejki priorytetowej. Realizacja kolejki priorytetowej w postaci ADT za pomocą jednego z drzew poszukiwań binarnych: drzewa ze wstawianiem jako liść, drzewa ze wstawianiem do korzenia, drzew wyważanych lub drzew czerwono-czarnych*. • Porównanie liczby elementarnych operacji czyli porównań, przypisań, operacji arytmetycznych, wyłuskań itd. dla realizacji kolejki priorytetowej za pomocą jednego z podanych drzew poszukiwań binarnych • Zastosowanie parametrów funkcyjnych do tworzenia kolejki priorytetowej wg różnych atrybutów danych: nazwiska, wieku itd. Proponowane zadania do wykonania: Program 1. Należy wykonać program, w którym są następujące opcje: 1.1 Wybór kryterium wstawiania i usuwania danych typu strukturalnego Osoba z kolejki: wg nazwiska lub wg wieku itp. 1.2 Wstawianie do kolejki, zrealizowanej za pomocą wybranego typu drzewa, danych w prowadzanych z klawiatury. 1.3 Usuwanie największego elementu 1.4 Wyświetlanie danych z kolejki za pomocą funkcji przejścia przez kolejkę Dla_kazdego, 1.5 Wykonanie eksperymentu do oceny czasochłonności operacji na kolejce priorytetowej 15.1. Wybór rozkładu danych wstawianych do kolejki np. wybór rozkładu losowego przez wywołanie funkcji srand z ustalonym parametrem, lub wybór danych posortowanych przez przygotowanie danych w tablicy, posortowanych w sposób rosnący lub malejący wg wybranej składowej w opcji 1.1. 1.5.2. Wykonanie eksperymentu: wstawienie 1000 danych do kolejki priorytetowej zgodnie z wybranym rozkładem danych (funkcja random lub pobranie danych posortowanych z tablicy). Zliczenie operacji elementarnych (patrz Wyjaśnienia) 1.5.3. Usunięcie 1000 danych z kolejki priorytetowej, zliczając operacje elementarne za pomocą liczników, używanych podczas wstawiania 1000 elementów w opcji 1.5.2. 1.5.4. Zapisanie w pliku wartości liczników elementarnych operacji 1.6 Prezentacja na ekranie liczby operacji zapisanych w pliku po wykonaniu eksperymentu z punktu 1.5. Zapamiętanie wyników liczenia operacji w pliku pozwoli porównać je z wynikami dla kolejki, budowanej na bazie jednej z list oraz stogu, tworzonych w laboratorium 4). 1.7 * Zapis do pliku funkcją Dla_kazdego podstawiając pod parametr funkcyjny funkcję zapisującą dane do pliku za pomocą fwrite 1.8 * Odczyt z pliku funkcją Dla_kazdego podstawiając pod parametr funkcyjny funkcję odczytującą dane z pliku za pomocą fread Wykonanie tej opcji jest tylko wtedy sensowne, gdy drzewo zapisane do pliku nie zmieni się lub gdy zostaną wykonywane jedynie operacje usuwania z drzewa (wtedy elementy z pliku powinny być zapisane na elementach drzewa nie zmieniając zasady, że elementy o większych wartościach wybranych atrybutów są umieszczane na lewo, a większe na prawo, natomiast równe są ignorowane – nadmiar elementów jest pomijany) !!! Inną realizacją tej opcji jest tworzenie drzewa od nowa w stawiając do niego odczytywane dane z pliku (wtedy uzyskamy drzewo posiadające prawe poddrzewo w postaci listy) i następnie wyważenie drzewa. Wyjaśnienia: • Funkcja Dla_kazdego (funkcja przechodząca przez wszystkie elementy drzewa w sposób rekurencyjny o przekładowym nagłówku void Dla_kazdego(PELEMENT Wezel, zrob funkcja), gdzie typ funkcja jest zdefiniowana jako typedef void (*zrob)(dane) oraz typedef struct Osoba dane dla drzewa. Może ona np. wyświetlać dane umieszczone w elementach kolejki na ekranie (jeśli podstawiona funkcja pod parametr funkcyjny funkcja typu zrob potrafi wyświetlić na ekranie dane umieszczone w elementach kolejki lub zapisywać je w pliku (jeśli podstawiona funkcja pod parametr funkcyjny funkcja typu zrob potrafi zapisywać w pliku dane umieszczone w elementach kolejki). void Dla_kazdego (PELEMENTD Wezel, zrob funkcja) //w programie przykładowe wywołanie Dla_kazdego(Korzen, Pokaz_dane) { /nagłówek funkcji void Pokaz_dane(dane Dane) if (Wezel!=NULL) { Dla_kazdego(Wezel->Lewy, funkcja); funkcja(Wezel->Dane); Dla_kazdego(Wezel->Prawy, funkcja); } } • Wybór kryterium wstawiania i usuwania z kolejki można zrealizować za pomocą przypisania nazwy funkcji porównującej wybrany atrybut do parametru funkcyjnego przekazywanego do funkcji wstawiającej i usuwającej (tak jak w funkcji Dla_kazdego) typedef int (*porownaj) (PELEMENTD a, PELEMENTD b); int por1 (PELEMENTD a, PELEMENTD b) { return strcmp (a->Dane.Nazwisko, b->Dane.Nazwisko); } int Wstaw(PELEMENTD &Wezel,PELEMENTD& Pozycja, porownaj p) { if (Wezel==NULL) { Wezel= Pozycja; return 0; } if ( p(Pozycja, Wezel)<0) return Wstaw(Wezel->Lewy, Pozycja, p); else if (p(Pozycja, Wezel)>0) return Wstaw(Wezel->Prawy, Pozycja, p); else { delete Pozycja; Pozycja=NULL; return 1; } } Wywołanie funkcji Wstaw: Wstaw(Korzen, Nowy, por1); • Wyznaczenie liczby elementarnych operacji typu porównania, przypisania, wywołania funkcji, operacji arytmetycznych, wyłuskań (np. struktura->składowa oznacza sumę: wyłuskanie + wybór składowej za pomocą operatora . (*wskstruktura).składowa) występujących przy wstawianiu 1000 danych, zależnych od rozkładu wstawianych danych i przy usuwaniu wszystkich elementów z kolejki. Ważne są łączne liczby wykonanych operacji elementarnych występujących w kodzie funkcji do wstawiania i usuwania (np. suma operacji porównania przy dodawaniu i usuwaniu 1000 elementów). Uwaga: 1) Można wprowadzić zmiany w pisanych programach, jeśli zostaną zachowane cele laboratorium 5. 2) Do laboratorium 5 dodano: • Program w katalogu drzewo_przykład – przykład tworzenia drzewa binarnego za pomocą wstawiania jako liść, do korzenia, wyważania drzewa oraz przeszukiwania oraz usuwania z drzewa. • Program w katalogu drzewo_baza – przykład tworzenia drzewa za pomocą wstawiania jako liść(opcja2), do korzenia (opcja1) w sposób automatyczny (losowanie 1000 elementów wstawianych do drzewa) oraz wstawianych w sposób automatyczny z jednoczesnym wyważaniem ( opcja6 – jako liść oraz opcja5-do korzenia). Program ten można przystosować do potrzeb programu podobnie postępując przy usuwaniu elementów z drzewa jako kolejki priorytetowej (usuwanie największego elementu)