Zmienne dynamiczne. nazwy; odwo lania do nich sa za pomoca być tworzone jawnie procedura zmienne dynamiczne maja

Podobne dokumenty
Podstawy Programowania. Listy i stosy

Drzewa podstawowe poj

Dynamiczne struktury danych

Drzewa AVL definicje

Informatyka 1. Przetwarzanie tekstów

Wskaźniki, funkcje i tablice

Tablice i funkcje. Marcin Makowski. 26 listopada Zak lad Chemii Teoretycznej UJ

Paradygmaty programowania. Paradygmaty programowania

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Wykład 6_1 Abstrakcyjne typy danych stos Realizacja tablicowa i za pomocą rekurencyjnych typów danych

Functionalization. Funkcje w C. Marcin Makowski. 30 listopada Zak lad Chemii Teoretycznej UJ

Paradygmaty programowania

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

Wstęp do programowania. Listy. Piotr Chrząstowski-Wachtel

Funkcje systemu Unix

Instrukcje podsumowanie. Proste: - przypisania - wejścia-wyjścia (read, readln, write, writeln) - pusta - po prostu ; (średnik) Strukturalne:

Programowanie w VB Proste algorytmy sortowania

P. Urzyczyn: Materia ly do wyk ladu z semantyki. Uproszczony 1 j. ezyk PCF

Paradygmaty programowania. Paradygmaty programowania

Wstęp do programowania

Lista dwukierunkowa. Grzegorz Wasylów Konrad Wojtoń

Wstęp do programowania. Stosy i kolejki. Piotr Chrząstowski-Wachtel

Język programowania PASCAL

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki

INFORMATYKA. Podstawy programowania w języku C. (Wykład) Copyright (C) 2005 by Sergiusz Sienkowski IME Zielona Góra


Ghost in the machine

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Laboratorium nr 9. Temat: Wskaźniki, referencje, dynamiczny przydział pamięci, tablice dynamiczne. Zakres laboratorium:

Informatyka I. Wyk lad I. Wprowadzenie. Robert Muszyński Instytut Cybernetyki Technicznej Politechnika Wroc lawska

E S - uniwersum struktury stosu

ZASADY PROGRAMOWANIA KOMPUTERÓW

OPERACJE NA PLIKACH. Podstawowe pojęcia:

Tablice hashowe. indeksowana

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

Podstawy programowania 2. Przygotował: mgr inż. Tomasz Michno

Podstawy programowania. Wykład PASCAL. Zmienne wskaźnikowe i dynamiczne. dr Artur Bartoszewski - Podstawy prograowania, sem.

Ada-95. Dariusz Wawrzyniak

Algorytmy i struktury danych

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Podstawy programowania

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wykład 5 Wybrane zagadnienia programowania w C++ (c.d.)

Podstawy programowania w języku C++

Dynamiczne struktury danych

Pascal. 1. Pliki tekstowe. Przykład 1.1. Zapis do pliku tekstowego

Wstęp do programowania

Wstęp do programowania. Drzewa podstawowe techniki. Piotr Chrząstowski-Wachtel

Obliczenia na stosie. Wykład 9. Obliczenia na stosie. J. Cichoń, P. Kobylański Wstęp do Informatyki i Programowania 266 / 303

Algorytmy i struktury danych. wykład 5

Wstęp do programowania. Procedury i funkcje. Piotr Chrząstowski-Wachtel

2.Sprawdzanie czy podana liczba naturalna jest pierwsza Liczba pierwsza to liczba podzielna tylko przez 1 i przez siebie.

Wstęp do programowania. Drzewa. Piotr Chrząstowski-Wachtel

Informatyka I. Wyk lad II Algorytm, podstawowe notacje, typy danych i wyrażenia

Wstęp do programowania. Różne różności

int tab_a [ 2 ] [ 3 ];

Programowanie w Turbo Pascal

Rozdzia l 3. Laboratorium 3. danych zawierajac

Podstawy programowania skrót z wykładów:

Organizacja systemu plików

Języki programowania obiektowego Nieobiektowe elementy języka C++

Lista 5 Typy dynamiczne kolejka

1. Abstrakcyjne typy danych

Struktury danych (I): kolejka, stos itp.

Języki programowania. Przetwarzanie tablic znaków. Część druga. Autorzy Tomasz Xięski Roman Simiński

Programowanie w języku C++

Struktury dynamiczne

Algorytmy i struktury danych. Wykład 6 Tablice rozproszone cz. 2

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

Podstawy programowania

Operacje na plikach. Organizacja systemu plików. Typy plików. Struktury plików. Pliki indeksowane. Struktura wewn etrzna

Materiał uzupełniający do ćwiczen z przedmiotu: Programowanie w C ++ - ćwiczenia na wskaźnikach

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Równoleg le sortowanie przez scalanie

Drzewa wielokierunkowe trie

Informatyka 1. Wyrażenia i instrukcje cd., ręczna symulacja, operacje wejścia/wyjścia

Ćwiczenie nr 520: Metody interpolacyjne planowania ruchu manipulatorów

Informatyka 1. Dokumentacja programu, moduły programowe, typy tablicowe

Wyk lad 3 Wielomiany i u lamki proste

Wykład 4. Tablice. Pliki

Stuck in the loop. Sterowanie. Marcin Makowski. 29 października Zak lad Chemii Teoretycznej UJ

Informatyka 1. Procedury i funkcje, struktura programu w Pascalu

Informatyka 1. Wyrażenia i instrukcje, złożoność obliczeniowa

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

Wyk lad 4 Macierz odwrotna i twierdzenie Cramera

Algorytmika i pseudoprogramowanie

Struktury. Przykład W8_1

Podstawy Informatyki. Wykład 6. Struktury danych

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Wyk lad 7 Metoda eliminacji Gaussa. Wzory Cramera

Funkcje i instrukcje języka JavaScript

Analiza algorytmów zadania podstawowe

Myśl w języku Python! : nauka programowania / Allen B. Downey. Gliwice, cop Spis treści

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Struktury danych: stos, kolejka, lista, drzewo

Wykład 3 Składnia języka C# (cz. 2)

Organizacja systemu plików

Informatyka I. Wykład 4. Tablice. Dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Zmienne i struktury dynamiczne

Transkrypt:

Zmienne dynamiczne pamieć dynamiczna: obszar pamieci, który program może wykorzystywać w sposób jawny, umieszczajac tam dane różnych typów przydzielanie (alokacja) pamieci zwalnianie (dealokacja) pamieci zmienne umieszczane w pamieci dynamicznej nazywamy zmiennymi dynamicznymi; różnia sie one od znanych nam zmiennych statycznych: sa anonimowe, tzn. nie maja nazwy; odwo lania do nich sa możliwe za pomoca wskaźników musza być tworzone jawnie procedura NEW zmienne dynamiczne maja nieograniczony zakres, tzn. można odwo lywać sie do nich z dowolnego miejsca programu; sa w pewnym sensie globalne (nie jest to zupe lnie ścis le ponieważ globalne lub lokalne moga być nazwy, a te zmienne nie maja nazw) zmienne dynamiczne istnieja dowolnie d lugo, tzn. do chwili jawnego ich skasowania procedura DISPOSE jednak tak samo jak dla zmiennych statycznych obowiazuje ścis le przestrzeganie zgodności typów Zmienne dynamiczne, wskaźniki, listy 1

Wskaźniki wskaźniki sa specjalnym typem danych, s lużacym wy l acznie do pos lugiwania sie zmiennymi dynamicznymi: operacje możliwe na wskaźnikach: przypisanie :=, porównanie =, i dostep do zmiennej dynamicznej ^ moga być parametrami i wartościa funkcji specjalna sta la wskaźnikowa NIL zmienne wskaźnikowe sa statyczne Zmienne dynamiczne, wskaźniki, listy 2

Przyk lad TYPE WskaznikInt = ^INTEGER; VAR i1, i2: WskaznikInt; {...} NEW(i1); {tworzymy zmienna dynamiczna } i1^ := 5; {nadajemy jej wartosc } WRITELN( Mamy zapamietana wartosc:,i1^); NEW(i2); {to samo dla drugiej zmiennej} i2^ := 5; WRITELN( Mamy zapamietana wartosc:,i2^); IF i1 = i2 THEN WRITELN( Wskazniki sa takie same. ) ELSE WRITELN( Wskazniki sa rozne. ); i2 := i1; {utozsamiamy wskazniki } IF i1 = i2 THEN WRITELN( Wskazniki sa takie same. ) ELSE WRITELN( Wskazniki sa rozne. ); i2^ := 7; {przypis.wart.jednej zm.dynam} IF i1^ = i2^ THEN WRITELN( Wartosci pozostaja takie same. ) ELSE WRITELN( Wartosci sa rozne. ) Zmienne dynamiczne, wskaźniki, listy 3

Graficzna ilustracja wskaźników i zmiennych dynamicznych VAR i1,i2: INTEGER; i1: i2: NEW(i1); i1: i2: i1 := 5; i1: i2: 5 NEW(i2); i1: 5 i2: i2 := 5; i1: 5 i2: 5 i2 := i1; i1: 5 i2: 5 zgubiona, zmienna nieużytek i2 := 7; i1: i2: 7 5 pamieci Zmienne dynamiczne, wskaźniki, listy 4

Lista regularna struktura dynamiczna TYPE T_Lista = ^T_Element; T_Element = RECORD info: T_info; nastepny: T_Lista; END; zmienne statyczne pami eć dynamiczna BD: info nast. info nast. info nast. info nast.... NIL dynamiczna struktura danych jest regularna struktura l acz ac a elementy treści z elementami konstrukcyjnymi (wskaźnikami) niezbedna jest co najmniej jedna zmienna statyczna zapewniajaca dostep do struktury dynamicznej specjalna wartość wskaźnikowa NIL jest przydatna do oznakowania pustych zakończeń struktury dynamicznej Zmienne dynamiczne, wskaźniki, listy 5

Listy tworzenie VAR BD, pom: T_Lista; BD := NIL; {zainicjuj pusta liste} WHILE NOT EOF(plik) DO {czytaj plik do konca } NEW(pom); {utworz elem.w pamieci} WczytajElement(plik,pom^); {wczytaj jego dane } pom^.nastepny := NIL; {to na wszelki wypadek} DodajElement(BD,pom); {wlacz elem.do listy } END; trzy etapy w procesie konstrukcji listy: stworzenie nowej zmiennej dynamicznej wpisanie do niej w laściwej treści utworzenie w laściwych wskaźników konstrukcyjnych dla w l aczenia nowego elementu do reszty listy należy pami etać o wartości znacznikowej NIL Zmienne dynamiczne, wskaźniki, listy 6

Listy tworzenie (2) PROCEDURE DodajElement1(VAR Lista: T_Lista; Element : T_Lista); {wersja 1: na poczatek listy} Element^.nastepny := Lista; Lista := Element; END; {DodajElement1} BD := NIL; NEW(pom); pom^.info := A ; DodajElement1(BD, pom); NEW(pom); pom^.info := B ; DodajElement1(BD, pom); NEW(pom); pom^.info := C ; DodajElement1(BD, pom); NEW(pom); pom^.info := D ; DodajElement1(BD, pom); BD: info nast. info nast. info nast. info nast. D C B A NIL Zmienne dynamiczne, wskaźniki, listy 7

Listy tworzenie (3) PROCEDURE DodajElement2(VAR Lista: T_Lista; Element : T_Lista); {wersja 2: na koniec listy, realizacja rekurencyjna} IF Lista = NIL THEN Lista := Element ELSE DodajElement2(Lista^.nastepny, Element); Element^.nastepny := NIL; {na pewno poprawne,choc moze niekonieczne} END; {DodajElement2} zauważmy, że sprawdzenie czy Lista = NIL dotyczy nie tyle przypadku pustej listy (poczatkowo), ale ogólnie przypadku końca listy; a wiec każdy nowy element bedzie wpisywany w te pusta wartość NIL zauważmy również, że ta niewinnie wygladaj aca procedura wykonuje przeszukiwanie ca lej istniejacej listy, w dodatku szeregiem tylu wywo lań rekurencyjnych, ile elementów ma lista Zmienne dynamiczne, wskaźniki, listy 8

Listy tworzenie (4) PROCEDURE DodajElement3(VAR Lista: T_Lista; Element : T_Lista); {wersja 3: na koniec listy, realizacja iteracyjna} VAR ostatni: T_Lista; IF Lista = NIL THEN Lista := Element ELSE ostatni := Lista; {wiemy ze Lista<>NIL} WHILE ostatni^.nastepny <> NIL DO ostatni := ostatni^.nastepny ostatni^.nastepny := Element; END; Element^.nastepny := NIL; {na pewno poprawne,choc moze niekonieczne} END; {DodajElement3} p etla WHILE znajduje ostatni element listy, dlaczego nie można: WHILE ostatni <> NIL DO ostatni := ostatni^.nastepny Zmienne dynamiczne, wskaźniki, listy 9

Zmienne dynamiczne, wskaźniki, listy 10

Listy tworzenie (5) dodawanie do listy elementu za wskazanym elementem: element^.nastepny := poprzedni^.nastepny; poprzedni^.nastepny := element; stad pomys l kolejnej wersji procedury dodawania elementu: PROCEDURE DodajElement4(VAR PoczatekListy, KoniecListy : T_Lista; Element : T_Lista); {wersja 4: na koniec listy ze wskazn.ostat.elemen.} IF PoczatekListy = NIL THEN PoczatekListy := Element; KoniecListy := Element END ELSE KoniecListy^.nastepny := Element; KoniecListy := Element; END; END; {DodajElement4} Zmienne dynamiczne, wskaźniki, listy 11

pos lugiwanie sie lista ze wskaźnikiem ostatniego elementu: VAR BD_pocz, BD_konc: T_Lista; { dwa wskazniki listy } {...} BD_pocz := NIL; BD_konc := NIL; { niekonieczne } Zmienne dynamiczne, wskaźniki, listy 12

Listy wyszukiwanie elementu FUNCTION PorownajElement(e1, e2: T_Element): CHAR; {...} {niech zwraca jeden ze znakow: <, =, > } {wersja 1 - zla; moze nie zatrzymac sie na koncu} pom := BD; WHILE PorownajElement(pom^, elem_wzorcowy) <> = DO pom := pom^.nastepny; {wersja 2 - tez zla; obie strony AND sa obliczane} pom := BD; WHILE (pom<>nil) AND PorownajElement(pom^, elem_wzorcowy) <> = DO pom := pom^.nastepny; {wersja 3 - dobra} pom := BD; znalazl := FALSE; WHILE (pom<>nil) AND (NOT znalazl) DO IF PorownajElement(pom^, elem_wzorcowy) = = THEN znalazl := TRUE ELSE pom := pom^.nastepny; Zmienne dynamiczne, wskaźniki, listy 13

{wersja 4 - dla list uporzadkowanych} pom := BD; znalazl := FALSE; minal := FALSE; WHILE (pom<>nil) AND (NOT znalazl) AND (NOT minal) DO CASE PorownajElement(pom^, elem_wzorcowy) OF > : minal := TRUE; = : znalazl := TRUE; < : pom := pom^.nastepny; END; {CASE} Zmienne dynamiczne, wskaźniki, listy 14

Listy tworzenie uporzadkowane PROCEDURE DodajElement5(VAR Lista: T_Lista; Element : T_Lista; FUNCTION PorownajElement(e1,e2:T_Element):CHAR); {wersja 5: w porzadku zgodnym z funkcja PorownajElement} { realizacja rekurencyjna} IF Lista = NIL THEN (* przypadek gdy lista jest pusta *) Element^.nastepny := NIL; Lista := Element; END ELSE CASE PorownajElement(Element^, Lista^) OF < : (* przypadek gdy element pasuje na poczatku *) Element^.nastepny := Lista; Lista := Element; END; = : ; (* przypadek gdy element jest juz na liscie *) > : (* przypadek ogolny, wstawiamy dalej na liste *) DodajElement5(Lista^.nastepny, Element, PorownajElement); END; {CASE} END; {DodajElement5} Zmienne dynamiczne, wskaźniki, listy 15

{realizacja iteracyjna przypadku ogolnego} poprzedni := Lista; dalej := TRUE; WHILE (poprzedni^.nastepny <> NIL) AND dalej DO IF PorownajElement(Element^, poprzedni^.nastepny^) = < THEN dalej := FALSE ELSE poprzedni := poprzedni^.nastepny; Element^.nastepny := poprzedni^.nastepny; poprzedni^.nastepny := Element; Zmienne dynamiczne, wskaźniki, listy 16

Listy usuwanie elementu Musimy odróżnić czynność wy l aczania elementu ze struktury danych od trwa lego unicestwiania elementu, i odzyskiwania zajmowanej pamieci (s luży do tego procedura DISPOSE). Najprostszy jest przypadek wy l aczenia z listy pierwszego elementu, w pewnym sensie analogiczny do wstawiania elementu na poczatek listy: PROCEDURE UsunElement1(VAR Lista: T_Lista; VAR Element: T_Lista); {wylacza pierwszy element z listy, i zwraca go w parametrze VAR} Element := Lista; Lista := Lista^.nastepny; END; {UsunElement1} zauważmy, że procedura nie sprawdza, czy lista nie jest przypadkiem pusta (co spowodowa loby b l ad wykonania) wy l aczanie z listy elementu, gdy mamy wskaźnik elementu poprzedniego poprzedni^.nastepny := poprzedni^.nastepny^.nastepny; Zmienne dynamiczne, wskaźniki, listy 17

Listy usuwanie elementu (2) Usuni ecie z listy konkretnego elementu, do którego mamy wskaźnik, wymaga przeszukiwania: PROCEDURE UsunElement2(VAR Lista: T_Lista; Element: T_Lista); {usuwa wskazany element z listy nie niszczac go - wersja rekurencyjna} IF Lista <> NIL THEN {lista pusta lub koniec wywolania rekurencyjnego} IF Lista=Element THEN Lista := Lista^.nastepny {tu nastepuje rzeczywiste wylaczanie} ELSE UsunElement2(Lista^.nastepny, Element); END; {UsunElement2} Wywo lanie rekurencyjne w ostatniej procedurze można zastapić petl a: pom := Lista; WHILE (pom^.nastepny <> NIL) AND (pom^.nastepny <> Element) DO pom := pom^.nastepny; IF pom^.nastepny = Element THEN pom^.nastepny := pom^.nastepny^.nastepny; Zmienne dynamiczne, wskaźniki, listy 18

Listy usuwanie elementu (3) Nie zawsze mamy jawny wskaźnik elementu, który chcemy usunać czesto wiemy tylko jaki element chcemy usunać; możemy wtedy porównywać kolejno wszystkie elementy z elementem wzorcowym. W ogólnym przypadku mamy schemat: el := ZnajdzElement(Lista, element_wzorcowy, PorownajElement); IF (el <> NIL) THEN UsunElement2(Lista, el); Zauważmy, że lista jest przeszukiwana dwa razy. Schemat ten możemy powtarzać aby usunać z listy kolejne (wszystkie) elementy pasujace do elementu wzorcowego. ostateczne kasowanie elementu ze zwalnianiem pami eci dynamicznej: DISPOSE(el); el := NIL; Przypisanie wskaźnikowi wartości NIL u latwia wykrywanie późniejszych b l ednych odwo lań do skasowanego elementu pami eci, ale im nie zapobiega! Zmienne dynamiczne, wskaźniki, listy 19

Zmienne dynamiczne, wskaźniki, listy 20

Listy usuwanie elementów (4) PROCEDURE UsunElementy1(VAR Lista : T_Lista; Element_wzorcowy: T_Element; FUNCTION PorownajElement(e1,e2:T_Element):CHAR); {usuwa z listy i niszczy elementy rownowazne wzorcowemu} {UWAGA: moze usuwac od konca do poczatku, lub na odwrot} VAR pom: T_Lista; IF (Lista <> NIL) THEN UsunElementy1(Lista^.nastepny, Element_wzorcowy, PorownajElement); IF PorownajElement(Lista^, Element_wzorcowy) = = THEN pom := Lista; Lista := Lista^.nastepny; {tu usuwamy 1 element } DISPOSE(pom); {tu odzyskujemy pamiec} END; END; END; {UsunElementy1} Zmienne dynamiczne, wskaźniki, listy 21

Listy usuwanie elementów (5) PROCEDURE UsunElementy2(VAR Lista : T_Lista; Element_wzorcowy: T_Element; FUNCTION PorownajElement(e1,e2:T_Element):CHAR); {realizacja iteracyjna, dziala tylko od poczatku do konca} VAR pom, dalej: T_Lista; dalej := Lista; WHILE (dalej <> NIL) DO IF PorownajElement(dalej^, Element_wzorcowy) = = THEN pom := dalej; dalej := dalej^.nastepny; IF Lista=pom THEN Lista:=dalej; {tu usuwamy 1 element } DISPOSE(pom); {tu odzyskujemy pamiec} END ELSE dalej := dalej^.nastepny; END; {UsunElementy2} Zmienne dynamiczne, wskaźniki, listy 22

Operacje na zmiennych dynamicznych Zmienne dynamiczne tworzone w procedurach nie znikaja w momencie zakończenia procedury lecz istnieja do chwili jawnego ich skasowania. Używajac w procedurach wskaźników jako parametrów nie możemy korzystać z wiedzy, czy sa to parametry VAR, czy zwyk le, aby zorientować sie, czy procedura może zmienić stan zmiennych globalnych zmienne dynamiczne sa zawsze globalne. W procedurach operujacych na dynamicznych strukturach danych trzeba szczególnie uważnie sprawdzać przypadki graniczne: koniec listy, pusta lista, pierwszy element, itp. Procedury i funkcje rekurencyjne sa szczególnie przydatne w operacjach na dynamicznych strukturach danych pozwalaja na prosty zapis skomplikowanych operacji i szybkie dopracowanie poprawnie funkcjonujacych programów jednak ich użycie jest znacznie bardziej kosztowne niż odpowiednich procedur iteracyjnych. Czasem stosuje sie podejście polegajace na użyciu procedur rekurencyjnych w wersji prototypowej programu, i przepisaniu wybranych procedur i funkcji na realizacje iteracyjne w wersji docelowej. Zmienne dynamiczne, wskaźniki, listy 23

Problemy ze wskaźnikami Typowym b l edem zdarzajacym sie w programach ze wskaźnikami jest wypadniecie przez koniec listy, co jest troch e podobne do przekroczenia zakresu indeksów tablicy. Wskaźniki umożliwiaja jednak pope lnianie znacznie wiecej rodzajów b l edów, np. używanie niezainicjowanych wskaźników, badź wskaźników do skasowanych zmiennych dynamicznych. Takie b l edy możemy latwiej wykrywać systematycznie ustawiajac nieużywane wskaźniki na NIL. Innym rodzajem b l edów jest gubienie wskaźników do zmiennych dynamicznych (tworzenie nieużytków pamieci), badź niezwalnianie niepotrzebnej pamieci dynamicznej, nawet jeśli nadal mamy do niej wskaźnik. Aby temu zaradzić dobrze jest systematycznie zwalniać każdy element pami eci dynamicznej w chwili, gdy sta l si e niepotrzebny. Jeszcze innym rodzajem b l edów, nie dajacym sie kontrolować w Pascalu (na szczeście?!), jest przypadek wyczerpania pamieci dynamicznej. Zmienne dynamiczne, wskaźniki, listy 24

Listy przegladanie PROCEDURE PrzegladajListe(l: T_Lista; PROCEDURE PrzegladajElement(e:T_Element)); (* wersja iteracyjna *) WHILE (l <> NIL) DO PrzegladajElement(l^); l := l^.nastepny; END; END; {PrzegladajListe} PROCEDURE PrzegladajListeR(l: T_Lista; PROCEDURE PrzegladajElement(e:T_Element)); (* wersja rekurencyjna *) IF (l <> NIL) THEN PrzegladajElement(l^); PrzegladajListeR(l,PrzegladajElement); END; END; {PrzegladajListeR} Zmienne dynamiczne, wskaźniki, listy 25

Listy przegladanie (cd.) wywo lanie procedury przegladania listy wymaga podania każdorazowo jako parametru aktualnego nazwy procedury o specyfikacji zgodnej z deklaracja parametru formalnego VAR BD: T_Lista; PROCEDURE WyswietlElement(el: T_Element); WRITELN( Nazwa elementu:, el.nazwa,, numer id:, el.id); END; {WyswietlElement} {...} PrzegladajListe(BD, WyswietlElement); Zmienne dynamiczne, wskaźniki, listy 26

Listy odwracanie PROCEDURE OdwrocListe(VAR lista: T_Lista); {przenoszenie elementow} PROCEDURE OdwrocListe2(VAR lista: T_Lista); {odwracanie wskaznikow w elementach} VAR elem, lista2: T_Lista; VAR nast, lista2: T_Lista; lista2 := NIL; lista2 := NIL; WHILE (lista <> NIL) DO WHILE (lista <> NIL) DO {zapamietujemy nast.element l-1} {usuw.el.z pocz.1-ej listy} nast := lista^.nastepny; elem := lista; {odwrac.wskaznik w 1-ym el. 1-1} lista := lista^.nastepny; lista^.nastepny := lista2; {i wlaczamy go do listy drugiej} {dodaj.na poczatek drugiej} lista2 := lista; elem^.nastepny := lista2; {przesuwamy wskaznik listy 1-ej} lista2 := elem; lista := nast; END; END; lista := lista2; END; {OdwrocListe} lista := lista2; END; {OdwrocListe2} Zmienne dynamiczne, wskaźniki, listy 27

Listy odwracanie, wersja rekurencyjna rekurencyjna realizacja odwracania listy jest skomplikowana; teoretycznie możliwe jest zapisanie rekurencyjnie pierwszej koncepcji odwracania, tzn. przenoszenia kolejnych elementów z jednej listy na druga, ale wymaga to innej specyfikacji nag lówka procedury, na przyk lad poprzez zewnetrzn a procedure owijajac a (ang. wrapper), i wewnetrzn a procedure w laściwa: PROCEDURE OdwrocListeR(VAR lista: T_Lista); VAR lista2: T_Lista; PROCEDURE OdwrocListeR_R(VAR l, l2: T_Lista); VAR e: T_Lista; IF l <> NIL THEN e := l; OdwrocListeR_R(l^.nastepny,l2); e^.nastepny := l2; l2 := e; END; END; {OdwrocListeR_R} lista2 := NIL; OdwrocListeR_R(lista, lista2); lista := lista2; END; {OdwrocListeR} Zmienne dynamiczne, wskaźniki, listy 28

Listy z g lowa TYPE T_WskElementu = ^T_Element; T_Element = RECORD info: T_info; nastepny: T_WskElementu; END; T_ListaZG = RECORD pierwszy: T_WskElementu; {inne informacje o liscie, np.: ostatni, dlugosc} END; VAR BD: T_ListaZG; {powinna byc statyczna} BD.pierwszy := NIL; {inicjalizacja listy} BD.dlugosc := 0; {itd.} zmienne statyczne pami eć dynamiczna BD: pierwszy: ostatni:... info nast. info nast. info nast. info nast.... NIL Zmienne dynamiczne, wskaźniki, listy 29

Listy z g lowa (2) zastosowania g lowy: przechowywanie dwóch wskaźników listy, pierwszego i ostatniego elementu, w celu np.: szybkiego dodawania wez lów na koniec listy szybkiego w l aczania ca lej listy w środek innej listy pojemnik na informacje: liczba elementów, liczba referencji, itp. umożliwienie usuwania pierwszego elementu listy, gdy wskaźnik listy jest skopiowany w kilku miejscach, np. w strukturach danych znacznik na listach ko lowych Zmienne dynamiczne, wskaźniki, listy 30

Listy z g lowa (3) użycie g lowy komplikuje procedury rekurencyjne: PROCEDURE DodajElement2(VAR Lista: T_ListaZG; Element : T_WskElementu); {na koniec listy: wersja rekurencyjna dla listy z glowa} PROCEDURE DodajElement2_R(VAR l: T_WskElementu; e : T_WskElementu); IF l = NIL THEN l := e ELSE DodajElement2_R(l^.nastepny, e); END; {DodajElement2_R} DodajElement2_R(Lista.pierwszy, Element); Element^.nastepny := NIL; END; {DodajElement2} Zmienne dynamiczne, wskaźniki, listy 31

Zmienne dynamiczne, wskaźniki, listy 32

Listy z wartownikiem pos lugiwanie sie lista ma pewne niespójności ponieważ operacje na wskaźniku listy czasem musza być różne dla listy pustej i niepustej możemy to zmienić stosujac zwyk ly schemat listy z dodatkiem wartownika (ang. guard), czyli dodatkowego elementu na końcu listy, którego treść jest nieistotna i nieużywana zmienne statyczne pami eć dynamiczna BD wart: BD: ost.element info nast. info nast. info nast.... wartownik Zmienne dynamiczne, wskaźniki, listy 33

Listy z wartownikiem (2) pos lugiwanie sie lista z wartownikiem: VAR BD, BD_wartownik: T_Lista; {inicjalizacja} NEW(BD_wartownik); BD := BD_wartownik; usprawnienia w kodzie, np. przeszukiwania, na jakie pozwala wartownik {atrakcyjny ale niepoprawny schemat przeszukiwania} pom := BD; WHILE (pom<>nil) AND PorownajElement(pom^, elem_wzorcowy) <> = DO pom := pom^.nastepny; IF (pom<>nil) THEN WRITELN( Znaleziony!, pom^...); {schemat jest poprawny dla listy z wartownikiem} pom := BD; WHILE (pom<>bd_wartownik) AND PorownajElement(pom^,elem_wzorcowy)<> = DO pom := pom^.nastepny; IF (pom<>bd_wartownik) THEN WRITELN( Znaleziony!, pom^...); Zmienne dynamiczne, wskaźniki, listy 34

Listy dwustronnie po l aczone TYPE T_ListaDP = ^T_Element; T_Element = RECORD info: T_info; poprzedni: T_ListaDP; nastepny: T_ListaDP; END; PROCEDURE DodajElementDP(VAR Lista: T_ListaDP; Element : T_ListaDP); {dodawanie elementu przed dowolnym elementem listy} Element^.nastepny := Lista; Element^.poprzedni := NIL; IF (Lista <> NIL) THEN Element^.poprzedni := Lista^.poprzedni; IF (Lista^.poprzedni <> NIL) THEN Lista.^poprzedni.^nastepny := Element; Lista.^poprzedni := Element; END ELSE Lista := Element; {konieczne bezwarunkowo gdyby zmienna Lista} END; {DodajElementDP} {miala wskazywac pierwszy element listy} Zmienne dynamiczne, wskaźniki, listy 35

listy dwustronnie po l aczone maja wiele cech odmiennych od zwyk lych list, np. można sie na nich cofnać, latwo w l aczać i usuwać elementy, dostep do listy zapewnia wskaźnik dowolnego elementu jednak zasadnicze cechy list pozostaja te same: sekwencyjny dostep do elementów, brak istotnych korzyści z porzadkowania elementów pos lugiwanie sie listami dwustronnie po l aczonymi jest bardziej z lożone niż zwyk lymi listami, np. trzeba uważać na koniec listy po obu stronach PROCEDURE UsunElementDP(VAR Lista: T_ListaDP; Element : T_ListaDP); {wylaczanie dowolnego elementu z listy} IF (Element^.nastepny <> NIL) {w el.nastepnym, zaktualizuj} THEN Element^.nastepny^.poprzedni := Element^.poprzedni; {poprzedni} ELSE IF (Element^.poprzedni <> NIL) {jesli istn.poprzedni,} THEN Element^.poprzedni^.nastepny := NIL; {wpisz,ze nie ma nast.} IF (Element^.poprzedni <> NIL) {w el.poprzednim,zaktualizuj} THEN Element^.poprzedni^.nastepny := Element^.nastepny; {nastepny} ELSE IF (Element^.nastepny <> NIL) {jesli istn.nastepny, } THEN Element^.nastepny^.poprzedni := NIL {wpisz,ze nie ma poprz} ELSE Lista := NIL; {w tym przyp.lista jest pusta} IF (Lista = Element) THEN {...}; {ten przyp.tez wymaga korekty} END; {UsunElementDP} Zmienne dynamiczne, wskaźniki, listy 36

Listy ko lowe zmienne statyczne pami eć dynamiczna BD: info nast. info nast. info nast. info nast.... listy ko lowe nie maja fizycznego końca (ani poczatku), nie maja pustych wskaźników NIL, i sa ca lkowicie symetryczne nadaja sie np. do realizacji tzw. buforów ko lowych, s lużacych do przechowywania pewnej ilości danych historycznych, automatycznie kasowanych w miare zapisywania nowych danych Zmienne dynamiczne, wskaźniki, listy 37

Po l aczenia czesto przydatne jest l aczenie różnych modyfikacji podstawowego schematu listy, np.: lista z wartownikiem i wskaźnikiem ostatniego elementu lista ko lowa dwustronnie po l aczona nie ma sensu dodawanie wartownika ani wskaźnika ostatniego elementu do listy ko lowej g lowa przydaje sie, i można ja dodać do każdego rodzaju listy Zmienne dynamiczne, wskaźniki, listy 38

Abstrakcyjne typy danych (wst ep) przez ATD (ang. ADT) rozumiemy określenie typu danych poprzez zdefiniowanie zestawu operacji, jakie maja być dlań dostepne ATD wnosza wyższy poziom abstrakcji niż typy danych definiowane w programach, i pozwalaja rozdzielić proces tworzenia programu na implementacje ATD, oraz pisanie w laściwego programu przy ich użyciu przyk lady ATD: stosy (LIFO) dodaj na stos (push) zdejmij ze stosu (pop) sprawdź szczyt stosu (top) sensowna realizacja przez zwyk le listy, a także tablice statyczne kolejki chronologiczne (FIFO) dodaj na koniec usuń z poczatku podaj d lugość kolejki (?) sensowna realizacja przez listy ze wskaźnikiem ostatniego elementu, a także tablice statyczne (z zawijaniem ) Zmienne dynamiczne, wskaźniki, listy 39