Złożone typy danych Listy Tworzenie elastycznych baz danych

Slides:



Advertisements
Podobne prezentacje
Wstawianie i wyszukiwanie kluczy w tablicach i drzewach binarnych
Advertisements

STRUKTURY DANYCH.
Algorytmy sortowania i porządkowania
Algorytmy sortowania i przeszukiwania
Algorytmy – c.d. złożoność algorytmów struktury danych
Algorytmy – c.d. struktury danych złożoność algorytmów
Klasa listy jednokierunkowej Przekazywanie parametrów do funkcji
Programowanie obiektowe PO PO - LAB 4 Wojciech Pieprzyca.
Standardowa biblioteka języka C++
Wskaźniki repetytorium Wskaźniki int Y = 1, X = 2; X = 5; int *p = &X; Y X p 4 4 p = &Y; *p = 4; 5.
Zaawansowane techniki algorytmiczne
Wzorce.
Dynamiczne struktury danych Listy, Kolejki, Stosy
Grażyna Mirkowska PJWSTK 15 listopad 2000
Programowanie I Rekurencja.
Filip Andrzejewski Remigiusz Chiluta
Języki programowania C++
27/09/ Języki programowania 1 Piotr Górczyński Pętle.
PROGRAMOWANIE STRUKTURALNE
Elementarne struktury danych Piotr Prokopowicz
Budowa i funkcje elektronicznego katalogu biblioteki szkolnej
Podstawy informatyki Powtórka Grupa: 1A Prowadzący: Grzegorz Smyk
Model danych oparty na listach
Tablice.
Algorytmy grafowe Reprezentacja w pamięci
Analiza kosztu zamortyzowanego
Typy wskaźnikowe, dynamiczne struktury danych
nowe operatory & . (kropka) * operator rzutowy -> , (przecinek)
Schemat Hornera Mgr inż. Michał Szucki.
POJĘCIE ALGORYTMU Pojęcie algorytmu Etapy rozwiązywania zadań
ADRESOWANIE WZGLĘDNE I BEZWZGLĘDNE Ćwiczenia
Podstawy informatyki (4)
Podstawy programowania
Zbiór do posortowania mieści się w pamięci
Podstawy programowania II
Operacje na strukturach listowych
Andrzej Jędryczkowski Nie da się napisać większego programu bez podziału go na części zwane podprogramami. Podprogram to wyróżniona część programu.
Łódź, 3 października 2013 r. Katedra Analizy Nieliniowej, WMiI UŁ Podstawy Programowania Złożona składnia języka C++
Przekazywanie argumentów
Edytor Vi.
Programowanie strukturalne i obiektowe
Andrzej Repak Nr albumu
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Elżbieta Fiedziukiewicz
Podstawy informatyki 2013/2014
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Programowanie obiektowe 2013/2014
Dynamiczne struktury danych
Podstawy języka Instrukcje - wprowadzenie
Programowanie strukturalne i obiektowe C++
Algorytmy i Struktury Danych
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++
Algorytmy i Struktury Danych Struktury Danych
Projektowanie postaci formularza:
Zbiory dynamiczne.
ALGORYTMY I STRUKTURY DANYCH
STOS. STL (ang. Standard Template Library) jest to biblioteka zawierająca algorytmy, pojemniki, iteratory oraz inne konstrukcje w formie szablonów, gotowe.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Indeksy drzewiaste. ISAM ISAM - INDEXED SEQUENTIAL ACCESS METHOD Problem: –Dany jest plik uporządkowany – w jaki sposób zrealizować efektywnie zapytanie.
Typy wyliczeniowe, kolekcje
Rozdział 5 REKURENCJA.
Listy.
Kolejka priorytetowa.
Wskaźniki Elżbieta Labocha.
Programowanie I Rekurencja.
nowe operatory & . (kropka) * operator rzutowy -> , (przecinek)
ALGORYTMY I STRUKTURY DANYCH
Zapis prezentacji:

Złożone typy danych Listy Tworzenie elastycznych baz danych Drzewa binarne Analiza symboliczna wyrażeń arytmetycznych Grafy Zagadnienia z dziedziny sztucznej inteligencji

Złożone typy danych – listy

Złożone typy danych – listy jednokierunkowe

Złożone typy danych – listy jednokierunkowe Pola: głowa, ogon i następny są wskaźnikami, natomiast wartość może być czymkolwiek: liczbą, znakiem, rekordem, itp.

Złożone typy danych – listy jednokierunkowe 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.

Złożone typy danych – listy jednokierunkowe 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

Złożone typy danych – listy jednokierunkowe Dla reprezentacji list jednokierunkowych typ w C++ może być zdefiniowany następująco: Typ może być dowolny, dla prostoty używamy typu int. 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.

Złożone typy danych – listy jednokierunkowe 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; } Ilustracja kodu ptr a a

Złożone typy danych – listy jednokierunkowe 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.

Złożone typy danych – listy jednokierunkowe Schemat wstawiania: Ćwiczenie: Implementacja

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

Złożone typy danych – listy jednokierunkowe 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. adres zdejm_se_stosu(adres pierwszy, int x) { adres zdjety; if (pierwszy != NULL) zdjety = pierwszy; pierwszy = (*pierwszy).nastepny; } return zdjety;

Złożone typy danych – listy jednokierunkowe Wady Zalety Nienaturalny dostęp do elementów Małe zużycie pamięci Niełatwe sortowanie Elastyczność 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; }

Złożone typy danych – listy jednokierunkowe Możliwości sortowania Alfabetycznie, wg nazwisk Wiek pracownika Kod pracownika Podczas sortowania list wskaźników dane w ogóle nie są ruszane – przemieszczaniu ulegają same wskaźniki. 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!

Złożone typy danych – listy jednokierunkowe

Złożone typy danych – listy jednokierunkowe 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.

Złożone typy danych – listy jednokierunkowe 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).

Złożone typy danych – listy jednokierunkowe Przykład: P R Z Y K Ł A D 5 2 -1 4 1 6 8 3 7 ? A D K Ł P R Y Z 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.

Złożone typy danych – listy jednokierunkowe Przykład: Minibaza danych zgrupowana w wyodrębnionej tablicy danych i trzy odrębne tablice wskaźników

Złożone typy danych – listy dwukierunkowe

Złożone typy danych – listy dwukierunkowe 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.

Złożone typy danych – listy dwukierunkowe 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.

Złożone typy danych – listy cykliczne 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.

Złożone typy danych – listy cykliczne 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++:

Złożone typy danych – listy cykliczne #include <iostream> 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<m;i++) x=x->next; //przesuwanie listy o m elementów x->next=x->next->next; //usuwanie elementu z listy } std:: cout<<x->info<<std::endl; //wyświetlanie danych std:: cout<<"Nacisnij <Enter>, aby kontynuowac.\n"; std:: cin.get(); return 0; /*deklaracja funkcji odpowiedzialnej za zamianę z char na liczbę integer*/ int atoi(char[]);

Złożone typy danych – stos 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.

Złożone typy danych – stos Stos i podstawowe operacje na nim: Stos tutaj ma pojemność dwóch elementów, na użytek przykładu, aby zilustrować efekt przepełnienia. 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ę.

Złożone typy danych – kolejka FIFO First In First Out FIFO ang. First in First out Kolejka (jak stos) zakłada dostęp ograniczony. 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.

Złożone typy danych – kolejka FIFO Implementacja może być za pomocą list jednokierunkowych lub za pomocą tablic.

Złożone typy danych – kolejka FIFO #include<stdio.h> #include<stdlib.h> 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

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

Złożone typy danych – kolejka FIFO 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

Złożone typy danych – kolejka FIFO #include<stdio.h> #include<stdlib.h> #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