Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Tworzenie elastycznych baz danych Listy Analiza symboliczna wyrażeń arytmetycznych Drzewa binarne Zagadnienia z dziedziny sztucznej inteligencji Grafy.

Podobne prezentacje


Prezentacja na temat: "Tworzenie elastycznych baz danych Listy Analiza symboliczna wyrażeń arytmetycznych Drzewa binarne Zagadnienia z dziedziny sztucznej inteligencji Grafy."— Zapis prezentacji:

1 Tworzenie elastycznych baz danych Listy Analiza symboliczna wyrażeń arytmetycznych Drzewa binarne Zagadnienia z dziedziny sztucznej inteligencji Grafy

2

3

4 Pola: głowa, ogon i następny są wskaźnikami, natomiast wartość może być czymkolwiek: liczbą, znakiem, rekordem, itp.

5 Przykład. Lista złożona z trzech elementów: 2, -12, 3. Jeśli lista jest pusta, to struktura informacyjna zawiera dwa wskaźniki i NULL. Pierwszy element listy jest złożony z jego własnej wartości (informacji do przechowania) oraz ze wskaźnika na drugi element listy, itd.

6 adres_tmp=info.głowa dopóki (adres_tmp !=NULL)wykonuj { jeśli(adres_tmp.wartość==x)to { wypisz "Znalzałem poszukiwany element" opuść procedurę } w przeciwym wypadku adres_tmp=adres_tmp.nastepny } wypisz "Nie znalazłem poszukiwanego elementu" Tak może wyglądać procedura przeglądająca elementy listy w poszukiwaniu wartości x

7 Dla reprezentacji list jednokierunkowych typ w C++ może być zdefiniowany następująco: struct element { int liczba; element *następny; }; typedef element *adres; Pozwala on konstruować listy jednokierunkowe (acykliczne) o długości ograniczonej wielkością tzw. sterty. Typ może być dowolny, dla prostoty używamy typu int.

8 Opisana poniżej funkcja realizuje operację wpisania na początek listy o adresie pierwszy liczbę całkowitą i. Funkcja zwraca adres pierwszego elementu listy rozbudowanej. adres wstaw_na_stos(adres pierwszy, int x) { element *a; a = new element; //a) (*a).liczba = x;//b) (*a).następny = pierwszy;//c) return a; } a a ptr Ilustracja kodu

9 Dużo bardziej złożona jest funkcja dołączająca nowy element w takie miejsce, aby całość listy była widziana jako posortowana. Ideę przedstawia rysunek: Nowy element może zostać wstawiony na początek (a), koniec (b) lub w środek (c). W istniejącej liście trzeba zrobić miejsce wstawienia, tzn. zapamiętać dwa wskaźniki: element, przed którym mamy wstawić nową komórkę i element, za którym trzeba to zrobić. Mogą być to zmienne przed i po.

10 Schemat wstawiania: Ćwiczenie: Implementacja

11 adres lista(int n) { adres pierwszy = NULL; pierwszy = wstaw_na_stos(pierwszy,random(5*n)); int i; for(i =1;i<=n-1;i++) pierwszy = wstaw_na_stos(pierwszy,random(5*n)); return pierwszy; } Następująca funkcja konstruuje dla liczby naturalnej n, listę jednokierunkową losowo wybranych liczb naturalnych z przedziału od 0 do 5n.

12 adres zdejm_se_stosu(adres pierwszy, int x) { adres zdjety; if (pierwszy != NULL) { zdjety = pierwszy; pierwszy = (*pierwszy).nastepny; } return zdjety; } Funkcja opisana poniżej usuwa z listy element o adresie pierwszy, określający początek listy. Funkcja zwraca adres usuwanego elementu. Zmienna pierwszy nadal przechowuje adres początku nowej listy.

13 WadyZalety Nienaturalny dostęp do elementów Małe zużycie pamięci Niełatwe sortowanieElastyczność Problem: Lista, do której nowe elementy wstawiamy zgodnie z pewnym porządkiem jest idealna, gdy mamy tylko jedno kryterium sortowania. Co zrobić, gdy elementami listy są rekordy o bardziej skomplikowanej strukturze? struct { char imie[20]; char nazwisko[30]; int wiek; int kod_pracownika; }

14 Możliwości sortowania Alfabetycznie, wg nazwisk Wiek pracownika Kod pracownika Jak rozwiązać?3 wersje list? Sortowanie list w pamięci? Obok listy danych dysponujemy kilkoma listami wskaźników do nich – tyle list, ile kryteriów sortowania! Podczas sortowania list wskaźników dane w ogóle nie są ruszane – przemieszczaniu ulegają same wskaźniki.

15

16 Tablicowa reprezentacja listy: I sposób (klasyczna reprezentacja): i-temu elementowi indeksu tablicy odpowiada i-ty element listy; musimy zarezerwować dużo miejsca, a lista ostatecznie może być krótka; trzeba wybrać zmienną, która zapamięta aktualną ilość elementów wstawionych wcześniej do listy.

17 Tablicowa reprezentacja listy: II sposób (metoda tablic równoległych): deklarujemy tablicę rekordów składających się z pola informacyjnego info (liczba, wartość) i pola typu całkowitego nastepny, które służy do odszukania następnego elementu na liście; można tu oddzielać tablice i mieć jedną tablicę na dane, a drugą na wskaźniki, lub nawet kilka tablic na wskaźniki ( w zależności od sposobu posortowania danych).

18 Przykład: P R Z Y K Ł A D ? ADKŁPRYZ? T[0]T[1]T[2]T[3]T[4]T[5]T[6]T[7]T[8] następny info T[0].następny – indeks pierwszego rzeczywistego elementu listy: 5, czyli w t[5].info znajduje się P Odczytujemy T[5].następny, tj. 6, więc w T[6].info jest R Odczytujemy T[6].następny, itd.

19 Przykład : Minibaza danych zgrupowana w wyodrębnionej tablicy danych i trzy odrębne tablice wskaźników

20

21 Lista dwukierunkowa: Pierwsza komórka na liście nie ma swojego poprzednika, zaznaczamy to wpisując NULL do pola poprzedni ; Ostatnia komórka nie posiada swojego następnika; zaznaczamy to, wpisując wartość NULL do pola następny. Zaletą listy dwukierunkowej jest szybkość działania, wadą – większa ilość pamięci niż w przypadku listy jednokierunkowej.

22 Dla reprezentacji list dwukierunkowych typ w C++ może być zdefiniowany następująco: struct element { int liczba; element *następny; element *poprzedni; }; typedef element *adres; Schemat usuwanie elementu p z listy dwukierunkowej Ćwiczenie: Schemat wstawiania.

23 Lista cykliczna jest zamknięta w pierścień: wskaźnik ostatniego elementu wskazuje pierwszy element. Element pierwszy jest wskazany umownie. Przykład: Problem Josephusa. n osób postanowiło wybrać przywódcę, robiąc wyliczankę m-sylabową, stojąc w kole. Na kogo padnie ostatnia, m-ta sylaba wyliczanki, ta odpada.

24 Przykład: Rozwiązanie problemu Josephusa. n osób postanowiło wybrać przywódcę, robiąc wyliczankę m-sylabową, stojąc w kole. Na kogo padnie ostatnia, m-ta sylaba wyliczanki, ta odpada. Tworzymy listę n-elementową cykliczną, zaczynając od jednego elementu, który wskazuje na siebie i wstawiamy za nim pozostałe elementy; Przetwarzamy listę odliczając m-1 elementów i usuwamy element o numerze m. Implementacja w C++:

25 #include struct element //element listy { int info; element *next; element(int x, element *t) {info = x; next =t;} }; typedef element *link; int main(int argc, char *argv[]) { //n-liczba elementów listy, m-oznacza, który element usuwamy int i,n =atoi(argv[1]),m=atoi(argv[2]); link t= new element(1,0); //pierwszy element listy t->next=t; link x=t; for(i=2;i<=n;i++) //utworzenie n-elementowej listy x=(x->next = new element(i,t)); while(x!=x->next) { for(i=1;i next; //przesuwanie listy o m elementów x->next=x->next->next; //usuwanie elementu z listy } std:: cout info<

26 Stos jest strukturą danych, do której dostęp jest możliwy tylko od strony tzw. wierzchołka. Last In First Out LIFO ang. push(x) – dokładanie danych na wierzchołek stosu pop(x) – zdjęcie, pobranie elementu x z wierzchołka stosu Nazwy funkcji wstaw_na_stos i zdejm_ze_stosu użyte wcześniej, nie zostały wybrane przypadkowo. Acykliczna lista jednokierunkowa wyposażona w funkcje dopisywania do listy pierwszego elementu i usuwania pierwszego elementu nosi właśnie nazwę stosu.

27 Stos i podstawowe operacje na nim: 1.Stos tutaj ma pojemność dwóch elementów, na użytek przykładu, aby zilustrować efekt przepełnienia. 2.Symboliczny stos znajdujący się pod każdą z 6 grup instrukcji ukazuje zawsze stan po wykonaniu swojej grupy instrukcji. Stos można implementować jako listę lub tablicę.

28 First In First Out FIFO ang. First inFirst out 1.Kolejka (jak stos) zakłada dostęp ograniczony. 2.Dwie podstawowe operacje: wstaw (wprowadź dane na ogon kolejki) i obsłuż (usuń – pobierz dane z czoła kolejki. Kolejka FIFO to inaczej acykliczna lista jednokierunkowa wyposażona w funkcje wstawiania na początek listy i usuwania elementu ostatniego na liście.

29 Implementacja może być za pomocą list jednokierunkowych lub za pomocą tablic.

30 #include struct elkol // przykładowa struktura kolejki { int wart; struct elkol *nast; }; struct kolejka { struct elkol *pocz; struct elkol *kon; }; void init(struct kolejka **k); //inicjowanie funkcji init int main(void) //główny program { struct kolejka *ko; init(&ko); return 0; }; void init(struct kolejka **k) //definiowanie funkcji init { (*k)->pocz = NULL; (*k)->kon = NULL; } Przykładowa implementacja

31 void initT(struct kolejkaT **kol) { (*kol)->p = 0; (*kol)->k = 0; } int EmptyT(struct kolejkaT **kol) { return (kol->k ==kol->p); } Funkcja ustawia kolejkę pustą Czy kolejka jest pusta void PushT(struct kolejkaT **kol, int x) { (*kol)->tabS[(*kol)->k] = x; (*kol)->k++; (*kol)->k = (*kol)->k%N; } Funkcja dodaje element na koniec

32 int FirstT(struct kolejkaT *kol) { return kol->tabS[kol->p]; } Funkcja podaje adres pierwszego elementu int LastT(struct kolejkaT *kol) { return kol->tabS[kol->k-1]; } Funkcja podaje adres ostatniego elementu int PoptT(struct kolejkaT *kol) { int elem = kol->tabS[kol->p]; kol->p = ((kol->p) + 1)%N; return elem; } Funkcja ściąga pierwszy element

33 #include #define N 100 struct kolejkaT { int tabS[N]; int p, k; }; void initT(struct kolejkaT **kol); void PushT(struct kolejkaT **kol, int x); int main(void) { struct kolejkaT *ko; initT(&ko); PushT(&ko,2); PushT(&ko,7); return 0; } void initT(struct kolejkaT **kol) { (*kol)->p = 0; (*kol)->k = 0; } void PushT(struct kolejkaT **kol, int x) { (*kol)->tabS[(*kol)->k] = x; (*kol)->k++; (*kol)->k = (*kol)->k%N; } Przykład dodania elementów do kolejki


Pobierz ppt "Tworzenie elastycznych baz danych Listy Analiza symboliczna wyrażeń arytmetycznych Drzewa binarne Zagadnienia z dziedziny sztucznej inteligencji Grafy."

Podobne prezentacje


Reklamy Google