Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 2/46 Plan wykł wykładu nr 2 Podstawy informatyki 2 Argumenty funkcji main Dynamiczne struktury danych stos kolejka lista Politechnika Biał Białostocka - Wydział Wydział Elektryczny Elektrotechnika, semestr II, studia stacjonarne drzewo Rok akademicki 2006/2007 jednokierunkowa dwukierunkowa cykliczna binarne Wykł Wykład nr 2 (07.03.2007) dr inŜ. Jarosław Forenc Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 3/46 Argumenty funkcji main Podstawy informatyki 2 Wykład nr 2 4/46 Argumenty funkcji main int main(int argc, char *argv[]) dr inŜ. Jarosław Forenc C:\>pr.exe par1 par2 par3 Argumenty funkcji main: argc = 4 argv[0] = pr.exe argv[1] = par1 argv[2] = par2 argv[3] = par3 #include <stdio.h> int main(int argc, char *argv[]) { int i; argc (ang. argument count) - liczba argumentów, z jakimi program został wywołany argv (ang. argument vector) - wskaźnik do tablicy zawierającej argumenty wywołania programu umieszczone w wierszu polecenia printf("Argumenty funkcji main:\n"); printf("argc = %d\n",argc); for (i=0;i<argc;i++) printf("argv[%d] = %s\n",i,argv[i]); Przykład: C:\>pr.exe par1 par2 par3 return 0; } argc = 4 argv[0] = argv[1] = argv[2] = argv[3] = ”C:\pr.exe” ”par1” ”par2” ”par3” Wyświetlenie argumentów funkcji main w przypadku programów uruchamianych bezpośrednio ze środowiska Dev-C++ argumenty wpisuje się wybierając: „Uruchom Parametry” Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 5/46 Dynamiczne struktury danych Podstawy informatyki 2 Wykład nr 2 stos (ang. stack) jest strukturą danych składającą się z elementów, z których kaŜdy posiada tylko adres następnika dostęp do danych przechowywanych na stosie jest moŜliwy tylko w miejscu określanym mianem wierzchołka stosu (ang. top) wierzchołek stosu jest jedynym miejscem, do którego moŜna dołączać lub z którego moŜna usuwać elementy kaŜdy składnik stosu posiada wyróŜniony element (wskaźnik next) zawierający adres następnego elementu wskaźnik ostatniego elementu stosu wskazuje na adres pusty (NULL) dane (data) są umowną nazwą pewnych struktur Elementami takich struktur mogą być: dane typów prostych, np. liczby, znaki dane typów złoŜonych, np. struktury, tablice, obiekty 6/46 Stos Dynamiczne struktury danych są to proste i złoŜone struktury danych, którym pamięć moŜe być przydzielana i zwalniana w trakcie wykonywania programu dr inŜ. Jarosław Forenc Do podstawowych dynamicznych struktur danych naleŜą: stos kolejka listy: jednokierunkowa dwukierunkowa cykliczna, jednokierunkowa cykliczna, dwukierunkowa drzewa Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 7/46 Stos Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 8/46 Stos nazwa stos odnosi się ściśle do funkcjonowania tej struktury - stos przypomina stertę kartek, na której wierzchołku moŜna połoŜyć kartkę lub ją zdjąć struktura stosu bywa nazywana stosem LIFO (ang. Last In First Out - ostatni wchodzi, pierwszy wychodzi) podstawowe operacje na stosie to: zdjęcie elementu ze stosu, czyli pobranie elementu ze stosu - funkcja pop() dane przechowywane na stosie są najczęściej pewną strukturą - dla uproszczenia przyjmijmy, Ŝe struktura skład się tylko z jednego pola typu int struct element { int x; }; ź dodanie elementu do stosu, czyli połoŜenie elementu na stosie - funkcja push() ródło: A. Zalewski: „Programowanie w j zykach C i C++ z wykorzystaniem pakietu Borland C++” ę Implementacja w języku C: kaŜdy składnik stosu skład się z „uŜytecznych” danych przechowywanych na stosie (data) oraz ze wskaźnika (next) zawierającego adres następnego elementu struct stos { struct element data; struct stos *next; }; Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 9/46 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 10/46 Stos Stos Implementacja w języku C - połoŜenie elementu na stosie: Implementacja w języku C - zdjęcie elementu ze stosu: funkcja dodająca element do stosu ma postać: funkcja usuwająca element ze stosu ma postać: struct stos *push(struct stos *top, struct element data) { struct stos *wsk; struct stos *pop(struct stos *top, struct element *data) { struct stos *wsk; if (top!=NULL) { wsk = top->next; *data = top->data; free(top); return wsk; } else return NULL; wsk = (struct stos*) malloc(sizeof(struct stos)); wsk->next = top; wsk->data = data; return wsk; } przykładowe wywołanie funkcji: } top = push(top,data); przykładowe wywołanie funkcji: top = pop(top,&data); przed pierwszym wywołaniem funkcji push(), wskaźnik top musi mieć wartość NULL Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 11/46 Stos - przykł przykład (1/3) Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 12/46 Stos - przykł przykład (2/3) #include <stdio.h> #include <stdlib.h> struct stos *push(struct stos *top, struct element data) { struct stos *wsk; struct element { int x; }; wsk = (struct stos*) malloc(sizeof(struct stos)); wsk->next = top; wsk->data = data; return wsk; struct stos { struct element data; struct stos *next; }; } Implementacja stosu w języku C struct stos *pop(struct stos *top, struct element *data) { struct stos *wsk; if (top!=NULL) { wsk = top->next; *data = top->data; free(top); return wsk; } else return NULL; } Implementacja stosu w języku C Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 13/46 Stos - przykł przykład (3/3) Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 14/46 Stos push() push() push() push() push() int main() { int tab[5] = {1,2,3,4,5}; struct stos *top = NULL; struct element data; int i; for (i=0;i<5;i++) { data.x = tab[i]; top = push(top,data); printf("push() --> %d\n",data.x); } pop() pop() pop() pop() pop() --> --> --> --> --> --> --> --> --> --> 1 2 3 4 5 Tablicowa implementacja stosu: przedstawiona wcześniej struktura stosu jest to tzw. listowa implementacja stosu istniej takŜe tablicowa implementacja stosu rozmiar tablicy jest stały i określany w momencie tworzenia stosu elementy stosu przechowywane są w tablicy, przy czym im później element został połoŜony, tym dalej w tablicy się znajduje wskaźnik stosu określa indeks tablicy, pod który zapisana zostanie następna dana umieszczana na stosie przy umieszczaniu danej na stosie indeks jest zwiększany, zaś przy zdejmowaniu danej ze stosu - zmniejszany 5 4 3 2 1 printf("\n"); while (top!=NULL) { top=pop(top,&data); printf("pop() --> %d\n",data.x); } system("pause"); return 0; } Implementacja stosu w języku C Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 15/46 Notacja polska Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 16/46 Odwrotna notacja polska notacja polska (zapis przedrostkowy, Notacja Łukasiewicza) jest to sposób zapisu wyraŜeń arytmetycznych, podający najpierw operator, a następnie argumenty odwrotna notacja polska - ONP (ang. Reverse Polish Notation, RPN) jest sposobem zapisu wyraŜeń arytmetycznych, w którym znak wykonywanej operacji umieszczany jest po argumentach, a nie pomiędzy nimi jak w konwencjonalnym zapisie algebraicznym wyraŜenie arytmetyczne: ma w notacji polskiej postać: wyraŜenie w notacji polskiej nie wymaga nawiasów, poniewaŜ przypisanie argumentów do operatorów wynika wprost z ich kolejności w zapisie wyraŜenie arytmetyczne: ma w odwrotnej notacji polskiej postać: notacja polska jest bliska naturalnemu sposobowi wyraŜania działań, w którym zazwyczaj najpierw podaje się czynność, a następnie dopełnia wyraŜenia wskazaniem rzeczy, do których czynność się odnosi, np. ONP została opracowana przez australijskiego naukowca Charlesa Hamblina jako „odwrócenie” beznawiasowej notacji polskiej Jana Łukasiewicza na potrzeby zastosowań informatycznych „podziel cztery przez sumę jednego i trzech” zapis wyraŜenia w ONP pozwala na całkowita rezygnację z uŜycia nawiasów w wyraŜeniach, gdyŜ jednoznacznie określa kolejność wykonywania działań ONP uŜywana jest w niektórych językach programowania (FORTH, Postscript) oraz w kalkulatorach naukowych HP: 4 / (1 + 3) / 4 + 1 3 notację polską przedstawił w 1920 roku polski matematyk Jan Łukasiewicz zapis wyraŜeń w notacji polskiej stał się podstawą języków: Logo, Tcl i LISP notacja polska była podstawą opracowania tzw. odwrotnej notacji polskiej (1 + 3) / 2 1 3 + 2 / programy komputerowe kompilujące program analizują wyraŜenie arytmetyczne i przekształcają je na ciąg instrukcji odpowiadający odwrotnej notacji polskiej otrzymane wyraŜenie obliczane jest podczas wykonywania programu Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 17/46 Odwrotna notacja polska Podstawy informatyki 2 Wykład nr 2 obliczenie wartości wyraŜenia arytmetycznego przy zastosowaniu odwrotnej notacji polskiej wymaga wykonania dwóch operacji: Zamiana wyraŜenia z notacji konwencjonalnej na ONP: zamiany notacji konwencjonalnej (nawiasowej) na odwrotną notację polską obliczenia wartości wyraŜenia arytmetycznego zapisanego w odwrotnej notacji polskiej oba powyŜsze algorytmy są bardzo proste i wykorzystują stos zamiana wykonywana jest przy zastosowaniu algorytmu Dijkstry nazywanego stacją rozrządową czytając wyraŜenie arytmetyczne od strony lewej do strony prawej operatory odkładamy na stos a liczby na wyjście wyjście naleŜy traktować jako kolejkę, która po zakończeniu algorytmu będzie zawierała wyraŜenie w odwrotnej notacji polskiej Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 19/46 wykonując powyŜsze operacje trzeba stosować następujące reguły: operator moŜemy odłoŜyć na stos tylko wtedy, jeśli ostatnim elementem stosu jest operator o niŜszym priorytecie jeŜeli ma on wyŜszy lub równy priorytet to zdejmujemy ze stosu dotąd elementy i wysyłamy na wyjście, aŜ ostatni operator będzie miał niŜszy priorytet lub stos będzie pusty jeśli kolejnym elementem jest nawias otwierający „(”, to odkładamy go na stos, bez względu na to co znajduje się w danym momencie na stosie i bez względu na to czy stos jest pusty powyŜszy nawias traktujemy jak dno stosu i odczytujemy kolejne elementy wyraŜenia według standardowego algorytmu jeśli dojdziemy do nawiasu zamykającego „)”, to nigdzie go nie odkładamy, tylko zdejmujemy kolejne operatory ze stosu i wysyłamy na wyjście, aŜ dojdziemy do nawiasu otwierającego, który równieŜ zdejmujemy ze stosu i wysyłamy na wyjście jeśli dojdziemy do końca wyraŜenia arytmetycznego, to zdejmujemy ze stosu pozostałe operatory i wysyłamy je na wyjście Podstawy informatyki 2 Wykład nr 2 Odwrotna notacja polska Odwrotna notacja polska Zamiana wyraŜenia z notacji konwencjonalnej na ONP - przykład: Obliczenie wartości wyraŜenia arytmetycznego w ONP: równanie w notacji konwencjonalnej: Krok 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 równanie w ONP: 18/46 Odwrotna notacja polska Zamiana wyraŜenia z notacji konwencjonalnej na ONP: dr inŜ. Jarosław Forenc (2+1)*3-4*(7+4) Wejście Stos ( 2 + 1 ) * 3 4 * ( 7 + 4 ) Koniec ( NULL ( NULL + ( NULL + ( NULL NULL * NULL * NULL - NULL - NULL * - NULL ( * - NULL ( * - NULL + ( * - NULL + ( * - NULL * - NULL - NULL NULL Wyjście 1 + 3 * 4 pobieramy kolejny element wyraŜenia jeśli elementem jest liczba to odkładamy ją na stos jeśli elementem jest operator, to pobieramy ze stosu tyle liczb, aby moŜna było „zastosować” operator na tych liczbach, np. dla dodawania, odejmowania, mnoŜenia i dzielenia są to dwie kolejne liczby, zaś dla negacji - jedna liczba wykonujemy operację na liczbach i jej wynik odkładamy na stos jeśli dotrzemy do końca wyraŜenia, to pobieramy wynik ze stosu, który jest wartością wyraŜenia arytmetycznego jeśli nie ma jeszcze końca, to wracamy na początek algorytmu 7 4 + * - 2 1 + 3 * 4 7 4 + * - Uwaga: 20/46 w algorytmie obliczania wartości wyraŜenia arytmetycznego zapisanego w odwrotnej notacji polskiej wykonujemy następujące operacje: 2 dr inŜ. Jarosław Forenc jeśli np. stos ma postać: 2 4 NULL i mamy wykonać operację dzielenia /, to operacja ta ma postać: 4 / 2, czyli do wykonania operacji argumenty brane są w odwrotnej kolejności Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 21/46 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 22/46 Odwrotna notacja polska Kolejka Obliczenie wartości wyraŜenia arytmetycznego w ONP - przykład: kolejka (ang. queue) jest strukturą danych składającą się z liniowo uporządkowanych elementów, do której moŜna dołączać elementy tylko w jednym końcu (na końcu kolejki), a usuwać tylko w drugim końcu (na początku kolejki) Działanie kolejka często określana jest jako stos FIFO (ang. First In First Out - pierwszy wchodzi, pierwszy wychodzi) 2 + 1 powiązanie między elementami kolejki jest takie samo, jak w przypadku stosu head jest wskaźnikiem na pierwszy element kolejki (początek kolejki), zaś tail - na ostatni element kolejki (koniec kolejki) równanie w ONP: Krok 1 2 3 4 5 6 7 8 9 10 11 12 równanie w ONP: 2 1 + 3 * 4 7 4 + * Wejście Stos 2 1 + 3 * 4 7 4 + * Koniec 2 NULL 1 2 NULL 3 NULL 3 3 NULL 9 NULL 4 9 NULL 7 4 9 NULL 4 7 4 9 NULL 11 4 9 NULL 44 9 NULL -35 NULL NULL 3 * 3 7 + 4 4 * 11 9 – 44 wynik: -35 -35 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 23/46 Kolejka korzystając z poprzedniej analogii, stosu kartek, moŜemy powiedzieć, Ŝe kładziemy kartki na wierzchołku stosu, zaś wyjmujemy ze spodu kolejkę moŜna takŜe wyobraŜać sobie jako typową kolejkę sklepową podstawowe operacje dotyczące kolejki to: usunięcie elementu z kolejki - Remove() lub dequeue() dane przechowywane w kolejce są najczęściej pewną strukturą - dla uproszczenia przyjmijmy, Ŝe struktura skład się tylko z jednego pola typu int struct element { int x; }; ź 24/46 Implementacja w języku C: ródło: A. Zalewski: „Programowanie w j zykach C i C++ z wykorzystaniem pakietu Borland C++” ę dołączenie elementu do kolejki - Insert() lub enqueue() dr inŜ. Jarosław Forenc Kolejka Podstawy informatyki 2 Wykład nr 2 kaŜdy składnik kolejki skład się z „uŜytecznych” danych przechowywanych w kolejce (data) oraz ze wskaźnika (next) zawierającego adres następnego elementu struct kolejka { struct element data; struct kolejka *next; }; Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 25/46 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 26/46 Kolejka Kolejka Implementacja w języku C - dołączenie elementu do kolejki: Implementacja w języku C - usunięcie elementu z kolejki: funkcja dodająca element do kolejki ma postać: funkcja usuwająca element z kolejki ma postać: struct kolejka *Insert(struct kolejka *tail, struct element data) { struct kolejka *wsk; struct kolejka *Remove(struct kolejka *head, struct element *data) { struct kolejka *wsk; wsk = (struct kolejka*) malloc(sizeof(struct kolejka)); wsk->data = data; wsk->next = NULL; if (tail != NULL) tail->next = wsk; return wsk; if (head!=NULL) { wsk = head->next; *data = head->data; free(head); return wsk; } else return NULL; } przykładowe wywołanie funkcji: head = tail = Insert(tail,data); tail = Insert(tail,data); } /* pierwsze wywołanie */ /* kolejne wywołania */ przykładowe wywołanie funkcji: head = Remove(head,&data); przed pierwszym wywołaniem funkcji head i tail powinny mieć wartość NULL Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 27/46 Kolejka - przykł przykład (1/3) Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 28/46 Kolejka - przykł przykład (2/3) #include <stdio.h> #include <stdlib.h> struct kolejka *Insert(struct kolejka *tail, struct element data) { struct kolejka *wsk; struct element { int x; }; wsk = (struct kolejka*) malloc(sizeof(struct kolejka)); wsk->data = data; wsk->next = NULL; if (tail != NULL) tail->next = wsk; return wsk; struct kolejka { struct element data; struct kolejka *next; }; } Implementacja kolejki w języku C struct kolejka *Remove(struct kolejka *head, struct element *data) { struct kolejka *wsk; if (head!=NULL) { wsk = head->next; *data = head->data; free(head); return wsk; } else return NULL; } Implementacja kolejki w języku C Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 29/46 Kolejka - przykł przykład (3/3) int main() { int tab[5] = {1,2,3,4,5}; struct kolejka *head, *tail; struct element data; int i; head = tail = NULL; for (i=0;i<5;i++) { data.x = tab[i]; if (i==0) head = tail = Insert(tail,data); else tail = Insert(tail, data); printf("Insert() --> %d\n",data.x); } Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 30/46 Lista Insert() Insert() Insert() Insert() Insert() --> --> --> --> --> 1 2 3 4 5 Remove() Remove() Remove() Remove() Remove() --> --> --> --> --> 1 2 3 4 5 listą (liniową) nazywamy liniowo uporządkowany zbiór elementów, z którego w dowolnym miejscu moŜna usunąć element, jak równieŜ dołączyć nowy element sposób budowy listy jest ściśle uzaleŜniony od zamierzeń programisty elementy moŜna wstawiać do listy na początku, na końcu lub w dowolnym innym miejscu (np. w celu przechowywania elementów posortowanych) w zaleŜności od powiązań pomiędzy elementami wyróŜniamy listy: jednokierunkowe dwukierunkowe cykliczne, jednokierunkowe cykliczne, dwukierunkowe printf("\n"); while (head!=NULL) { head = Remove(head,&data); printf("Remove() --> %d\n",data.x); } return 0; Implementacja kolejki w języku C } Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 31/46 Lista jednokierunkowa organizacja listy jednokierunkowej podobna jest do organizacji stosu i kolejki, tzn. dla kaŜdego składnika (poza ostatnim) jest określony następny składnik (lub poprzedni - zaleŜnie od implementacji) Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 32/46 Lista jednokierunkowa Implementacja w języku C: zapamiętywany jest wskaźnik tylko na pierwszy element listy lub wskaźniki na pierwszy i ostatni element listy dane przechowywane na liście są najczęściej pewną strukturą - dla uproszczenia przyjmijmy, Ŝe struktura skład się tylko z jednego pola typu int struct element { int x; }; kaŜdy składnik listy skład się z „uŜytecznych” danych przechowywanych na liście (data) oraz ze wskaźnika (next) zawierającego adres następnego elementu struct lista { struct element data; struct lista *next; }; Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 33/46 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 34/46 Lista jednokierunkowa Lista jednokierunkowa Implementacja w języku C - dołączenie elementu na początku listy: Implementacja w języku C - dołączenie elementu na końcu listy: funkcja dodająca element na początku listy ma postać: funkcja dodająca element na końcu listy ma postać: struct lista *dodaj_pierwszy(struct lista *first, struct element data) struct lista *dodaj_ostatni(struct lista *last, struct element data) { { struct lista *wsk; struct lista *wsk; wsk = (struct lista*) malloc(sizeof(struct lista)); wsk->data = data; wsk->next = first; wsk = (struct lista*) malloc(sizeof(struct lista)); wsk->data = data; wsk->next = NULL; if (last!=NULL) last->next = wsk; return wsk; return wsk; } } przykładowe wywołanie funkcji: first = last = dodaj_pierwszy(first,data); /* pierwsze wywołanie */ first = dodaj_pierwszy(first,data); /* kolejne wywołania */ przed pierwszym wywołaniem funkcji wskaźnik first powinien mieć wartość NULL Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 35/46 przykładowe wywołanie funkcji: first = last = dodaj_ostatni(last,data); /* pierwsze wywołanie */ last = dodaj_ostatni(last,data); /* kolejne wywołania */ przed pierwszym wywołaniem funkcji wskaźnik last powinien mieć wartość NULL Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc Lista jednokierunkowa Lista jednokierunkowa Implementacja w języku C - usunięcie wszystkich elementów: Implementacja w języku C - wyświetlenie wszystkich elementów: funkcja usuwająca wszystkie elementy z listy ma postać: struct lista *usun_wszystko(struct lista *first) { struct lista *wsk; while (first!=NULL) { wsk = first->next; free(first); first = wsk; } return first; } przykładowe wywołanie funkcji: first = last = usun_wszystko(first); funkcja wyświetlająca wartość wszystkich elementów listy: void wyswietl_liste(struct lista *first) { while (first!=NULL) { printf("Lista --> %d\n",first->data.x); first = first->next; } } przykładowe wywołanie funkcji: wyswietl_liste(first); 36/46 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 37/46 Lista jednokierunkowa - przykł przykład (1/5) Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 38/46 Lista jednokierunkowa - przykł przykład (2/5) #include <stdio.h> #include <stdlib.h> struct lista *dodaj_pierwszy(struct lista *first, struct element data) { struct lista *wsk; struct element { int x; }; wsk = (struct lista*) malloc(sizeof(struct lista)); wsk->data = data; wsk->next = first; return wsk; struct lista { struct element data; struct lista *next; }; } Implementacja listy jednokierunkowej w języku C struct lista *dodaj_ostatni(struct lista *last, struct element data) { struct lista *wsk; wsk = (struct lista*) malloc(sizeof(struct lista)); wsk->data = data; wsk->next = NULL; if (last!=NULL) last->next = wsk; return wsk; } Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 39/46 Lista jednokierunkowa - przykł przykład (3/5) struct lista *usun_wszystko(struct lista *first) { struct lista *wsk; while (first!=NULL) { wsk = first->next; free(first); first = wsk; } return first; } void wyswietl_liste(struct lista *first) { while (first!=NULL) { printf("Lista --> %d\n",first->data.x); first = first->next; } } Implementacja listy jednokierunkowej w języku C Implementacja listy jednokierunkowej w języku C Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 40/46 Lista jednokierunkowa - przykł przykład (4/5) int main() { int tab[5] = {1,2,3,4,5}; struct lista *first = NULL, *last = NULL; struct element data; int i; for (i=0;i<5;i++) { data.x = tab[i]; if (i==0) first = last = dodaj_pierwszy(first,data); else first = dodaj_pierwszy(first,data); printf("dodaj_pierwszy() --> %d\n",data.x); } dodaj_pierwszy() dodaj_pierwszy() dodaj_pierwszy() dodaj_pierwszy() dodaj_pierwszy() Lista Lista Lista Lista Lista --> --> --> --> --> --> --> --> --> --> 1 2 3 4 5 5 4 3 2 1 printf("\n"); wyswietl_liste(first); first = last = usun_wszystko(first); Implementacja listy jednokierunkowej w języku C Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 41/46 Lista jednokierunkowa - przykł przykład (5/5) printf("\n\n"); for (i=0;i<5;i++) { data.x = tab[i]; if (i==0) first = last = dodaj_ostatni(last,data); else last = dodaj_ostatni(last,data); printf("dodaj_ostatni() --> %d\n",data.x); } Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 42/46 Lista dwukierunkowa dodaj_ostatni() dodaj_ostatni() dodaj_ostatni() dodaj_ostatni() dodaj_ostatni() Lista Lista Lista Lista Lista --> --> --> --> --> --> --> --> --> --> 1 2 3 4 5 w liście dwukierunkowej kaŜdy węzeł posiada adres następnika, jak i poprzednika W strukturze tego typu wygodne jest przechodzenie pomiędzy elementami w obu kierunkach (od początku do końca i odwrotnie) 1 2 3 4 5 printf("\n"); wyswietl_liste(first); first = last = usun_wszystko(first); system("pause"); return 0; } Implementacja listy jednokierunkowej w języku C Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc Lista cykliczna listę cykliczną moŜna utworzyć z listy jednokierunkowej lub dwukierunkowej, jeśli ostatni element tej struktury połączymy z pierwszym Jednokierunkowa: Dwukierunkowa: 43/46 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc Drzewo drzewo jest najbardziej ogólną dynamiczną strukturą danych i moŜe być reprezentowane graficznie na róŜne sposoby korzeń drzewa jest umieszczony u góry skojarzone z korzeniem poddrzewa połączone są z korzeniem liniami zwanymi gałęziami drzewa potomkiem węzła w nazywamy kaŜdy, róŜny od w, węzeł naleŜący do drzewa, w którym w jest korzeniem węzeł w nazywamy przodkiem węzłów drzewa, w którym w jest korzeniem bezpośrednich potomków nazywamy synami bezpośrednich przodków nazywamy ojcami synów tego samego ojca nazywamy braćmi węzeł, który nie ma potomków, to liść drzewa 44/46 Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc 45/46 Drzewo binarne drzewo binarne jest szczególnym przypadkiem ogólnej struktury zwanej drzewem kaŜdy wierzchołek drzewa ma co najwyŜej dwóch potomków, tzn. kaŜdy ojciec ma co najwyŜej dwóch synów Podstawy informatyki 2 Wykład nr 2 dr inŜ. Jarosław Forenc Binarne drzewo wyszukiwawcze jest to drzewo binarne, w którym dla kaŜdego węzła wi wszystkie klucze (przechowywane wartości) w lewym poddrzewie węzła wi są mniejsze od klucza w węźle wi, a wszystkie klucze w prawym poddrzewie węzła wi są większe od klucza w węźle wi największą zaletą takiej struktury jest szybkość wyszukiwania informacji 46/46