Dynamiczne struktury danych: listy



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

Wskaźniki i struktury. Programowanie C, LA Anna Gogolińska

ZASADY PROGRAMOWANIA KOMPUTERÓW

Programowanie obiektowe

Rysunek 1 Przykładowy graf stanów procesu z dyskretnymi położeniami.

Obszar Logistyka. Rejestracja faktury zakupowej Rejestracja faktury zakupowej z pozycjami towarowymi. Instrukcja użytkownika

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Ćwiczenie 2 Wczytywanie i zapisywanie do plików tekstowych

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

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

Janusz Górczyński. Prognozowanie i symulacje w zadaniach

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Podstawy Programowania


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

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

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

Dynamiczny przydział pamięci w języku C. Dynamiczne struktury danych. dr inż. Jarosław Forenc. Metoda 1 (wektor N M-elementowy)

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja, - liczby losowe

Ada-95. Dariusz Wawrzyniak

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja cz. 1

Kiedy potrzebne. Struktura (rekord) Struktura w języku C# Tablice struktur. struktura, kolekcja

Lista 5 Typy dynamiczne kolejka

Laboratorium z przedmiotu Programowanie obiektowe - zestaw 04

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

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

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

Struktury danych: stos, kolejka, lista, drzewo

Algorytmy i struktury danych. wykład 5

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

Wykład 8: klasy cz. 4

Zmienne i struktury dynamiczne

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

1. Algorytmy przeszukiwania. Przeszukiwanie wszerz i w głąb.

PODSTAWY INFORMATYKI wykład 4.

Wykład 1: Wskaźniki i zmienne dynamiczne

Wstęp do programowania 2

Lista, Stos, Kolejka, Tablica Asocjacyjna

PLIKI TEKSTOWE F C E 30 0D 0A 42 6F 72 6C 61 6E 64 1A T U R B O _ P A S C A L _ 7. 0

Wykład 9: Polimorfizm i klasy wirtualne

( n) Łańcuchy Markowa X 0, X 1,...

INSTRUKCJA PUSTA. Nie składa się z żadnych znaków i symboli, niczego nie robi. for i := 1 to 10 do {tu nic nie ma};

Wstęp do programowania 2

Struktury. Przykład W8_1

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

Język programowania PASCAL

< K (2) = ( Adams, John ), P (2) = adres bloku 2 > < K (1) = ( Aaron, Ed ), P (1) = adres bloku 1 >

BeStCAD - Moduł INŻYNIER 1

Zasady programowania Dokumentacja

Programowanie i struktury danych. Wykład 4 Dr Piotr Cybula

Wykład IV PASCAL - łańcuch znaków, - procedury i funkcje, - sortowanie bąbelkowe

Struktury danych (I): kolejka, stos itp.

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

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

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych:

Drzewa poszukiwań binarnych

6 6.1 Projektowanie profili

INFORMATYKA W SZKOLE. Podyplomowe Studia Pedagogiczne. Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227

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

Algorytmika i pseudoprogramowanie

Abstrakcyjne struktury danych - stos, lista, drzewo

WYŻSZA SZKOŁA INFORMATYKI STOSOWANEJ I ZARZĄDZANIA

Wstęp do programowania 2

PRZESTRZENNE BAZY DANYCH WYKŁAD 2

Systemy operacyjne. Laboratorium 9. Perl wyrażenia regularne. Jarosław Rudy Politechnika Wrocławska 28 lutego 2017

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u

Analiza nośności pionowej pojedynczego pala

Diagramy klas. dr Jarosław Skaruz

Wykład PASCAL - Pliki tekstowe

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

Podstawowe struktury danych

Wykład 3. Złożoność i realizowalność algorytmów Elementarne struktury danych: stosy, kolejki, listy

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

Podstawy Informatyki. Wykład 6. Struktury danych

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Algorytmy i struktury danych Laboratorium 7. 2 Drzewa poszukiwań binarnych

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

Podstawy Programowania 2

Lab 9 Podstawy Programowania

Wstęp do wskaźników w języku ANSI C

ZASOBY ZMIENNYCH W STEROWNIKACH SAIA-BURGESS

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

ALGORYTMY OPTYMALIZACJI wyklad 3.nb 1. Wykład 3. Sformułujemy teraz warunki konieczne dla istnienia rozwiązań zagadnienia optymalizacyjnego:

Wykład 5: Klasy cz. 3

1 Wskaźniki i listy jednokierunkowe

Oracle PL/SQL. Paweł Rajba.

Podstawy Programowania C++

Pascal - wprowadzenie

ALGORYTM STRAŻAKA W WALCE Z ROZLEWAMI OLEJOWYMI

Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

Języki programowania zasady ich tworzenia

Pierwsze kroki z easy Soft CoDeSys Eaton Corporation. All rights reserved.

lekcja 8a Gry komputerowe MasterMind

Lekcja 6: Pascal. Procedura i funkcja

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Programowanie w SQL procedury i funkcje. UWAGA: Proszę nie zapominać o prefiksowaniu nazw obiektów ciągiem [OLIMP\{nr indeksu}] Funkcje użytkownika

138 Forum Bibl. Med R. 4 nr 1 (7)

Laboratorium Metod i Algorytmów Sterowania Cyfrowego

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Transkrypt:

Dynamiczne struktury danych: listy Mirosław Mortka Zaczynając rogramować w dowolnym języku rogramowania jesteśmy zmuszeni do oanowania zasad osługiwania się odstawowymi tyami danych. Na rzykład w języku Pascal osługujemy się m.in. tyami: integer, real, string, array, record it. Zmienne zadeklarowane za ich omocą nazywamy zmiennymi statycznymi. Ich zastosowanie łączy się z uzyskaniem wielu zalet, choćby sójność danych czy szybki dostę do elementów. Posiadają jednak bardzo istną wadę, mocno ograniczającą możliwość ich zastosowania: musimy z góry określić wielkość i ilość elementów. Jednakże wiele zagadnień charakteryzuje się zmiennością struktur danych odczas rocesu obliczeniowego. W tym wyadku z omocą rzychodzą nam zmienne dynamiczne. Niewątliwą korzyścią wynikającą ze stosowania tych tyów jest możliwość określenia wielkości zajmowanej rzez nich amięci doiero w trakcie trwania rogramu. Taka deklaracja struktury danych owoduje jednak, iż komilator nie jest w stanie określić konkretnych adresów dla oszczególnych zmiennych ani rzydzielić na nie amięci. W konsekwencji zmuszeni jesteśmy do dynamicznego rzydzielania amięci, tzn. rzydzielania amięci zmiennym w momencie użycia ich rzez rogram (utworzenia nowej zmiennej w trakcie wykonania rogramu) zamiast rzydzielania im stałej ilości amięci odczas translacji rogramu. Komilator rzydziela wtedy stałą ilość amięci na adres zmiennej umieszczanej dynamicznie w amięci zamiast na samą zmienną. Zmienne, które zawierają adres i tym samym wskazują ołożenie innego obiektu lub zmiennej w amięci, nazywamy wskaźnikami. W języku Pascal zmienną wskaźnikową oznaczamy ^. Korzystając z dynamicznych struktur danych możemy oerować na listach, drzewach czy grafach. Listy jednokierunkowe Najrostszym sosobem ozwalającym gruować dowolną ilość danych (ograniczoną tylko rozmiarem dostęnej amięci) jest lista jednokierunkowa (atrz rys. 1). W tym rzyadku każdy element jest ojedynczym rekordem składającym się z co najmniej dwóch ól: ola wartości i wskaźnika do nastęnego elementu listy. Wartością wskaźnika umożliwiającą jednoznaczne zidentyfikowanie ostatniego elementu listy w języku Pascal jest secjalna wartość nil (NULL w C/C++). o Rys. 1. Przykład listy jednokierunkowej

W rzyadku list jednokierunkowych nie jest możliwy bezośredni dostę do dowolnego jej elementu. Ponieważ każdy element osiada jedynie wskaźnik do jego nastęnika, więc dotarcie do n-tego elementu listy wymaga wcześniej rzejścia rzez n-1 orzedników. Oto najrostsze oeracje, jakie możemy wykonać na liście jednokierunkowej: wstawienie elementu na zątek listy, wstawienie elementu na koniec listy, usunięcie ierwszego elementu listy, odczyt ierwszego elementu listy, dostę do dowolnego elementu listy. W zależności od wyboru odstawowych oeracji wykonywanych na liście możemy wyróżnić dwa odstawowe rodzaje struktur imlementowanych na odstawie list jednokierunkowych: stos: możliwe jest wstawianie, usuwanie i odczyt ierwszego elementu listy wierzchołka; tego tyu struktura nazywana jest LIFO 1 (rys. 2), kolejka (ojedyncza, jednokierunkowa): wstawianie elementu na koniec listy, odczyt i usuwanie elementu ierwszego struktura tyu FIFO 2 (rys. 3). wierzchołek wstawianie, usuwanie, odczyt dno stosu Rys. 2. Struktura stosu kon usuwanie, odczyt wstawianie Rys. 3. Struktura kolejki 1 ang. last in, first out 2 ang. first in, first out 2

Podstawowe oeracje dotyczące listy jednokierunkowej omówimy na odstawie zadania 1. Zadanie 1. Naisać rogram odwracający lik tekstowy lik.wej. Wynikiem wykonania rogramu ma być drugi lik tekstowy lik.wyj. Pierwszym wierszem liku wyjściowego ma być ostatni wiersz liku wejściowego, drugim rzedostatni itd. Założyć, że wiersze nie rzekraczają 255 znaków 3. Rozwiązanie Definiowanie listy w Pascalu Zdefiniujmy ty elementów listy wierszy liku. Każdy taki element zawiera ciąg znaków hodzący z kolejnej linii liku tekstowego oraz wskaźnik do elementu nastęnego. W języku Pascal definicja ta będzie miał nastęujący wygląd: tye PElem = ^TElem; (1) TElem = record (2) s: string; nast: ^TElem; (3) Zaczynamy od zdefiniowania tyu wskaźnikowego PElem do danych tyu TElem (1). Druga definicja (2) narzuca strukturę każdej zmiennej tyu TElem składającą się z dwóch ól: s zawierającego linię tekstu liku oraz nast zawierającego wskaźnik do nastęnego elementu. ^ to symbol wskaźnika. Deklarując zmienną tyu PElem, używamy zaisu ^ do wskazania rekordu tyu TElem. Wśród zmiennych globalnych musimy zadeklarować zmienną tyu PElem wskazującą na zątek listy wykorzystywanej w zadaniu. var : PElem; Uwaga: Składnia języka Pascal zabrania użycia nazwy, której znaczenie nie zostało wcześniej zdefiniowane. Definicja tyu wskaźnikowego wykorzystującą nazwę obiektu wskazywanego jest jedynym wyjątkiem od tej reguły. 3 K.Jakubczyk: Turbo Pascal i Borland C++. Przykłady., Helion, Gliwice2002, s. 149 3

Dodawanie nowego elementu na zątek listy Wstawienie elementu na zątek listy wymaga wykonania dwóch oeracji rzyisania wartości zmiennym tyu wskaźnikowego: a) nadanie olu nast wskazywanemu rzez wskaźnik wartości adresu rzechowywanego rzez wskaźnik do zątku listy (rys. 4a); ^.nast:= ; b) uaktualnienie wartości zmiennej orzez rzyisanie jej wartości wskaźnika do elementu (element zostaje umieszczony na ierwszym miejscu listy rys. 4b). := ; a) b) Rys. 4. Dodanie elementu na zątek listy Wstawianie elementu na zątek listy możliwe jest wówczas, gdy element istnieje (został wcześniej utworzony). W rzeciwnym wyadku musimy utworzyć nowy element i uaktualnić jego ola (nadać im wartości zątkowe). Procedurą rzydzielającą amięć oraz generującą wskaźnik do nowego elementu jest olecenie new. new(); ^.s:= Początkowa wartość ; Procedura wczytującą kolejne linie tekstu i umieszczającą je na zątku listy będzie zatem miała nastęujący wygląd: 4

rocedure UtworzListe; var : PElem; {wskaźnik omocniczy} f: text; {zmienna rerezentującą lik tekstowy} s: string; {zmienna omocnicza do wczytywania linii tekstu z liku} Assign(f,'lik.wej'); {otworzenie liku} Reset(f); {do odczytu} :=nil; {zątkowo lista jest while not Eof(f) do ReadLn(f,s); usta} {doóki nie został osiągnięty koniec liku} {czytaj linię tekstu z liku} new(); {utwórz nowy element } ^.s:= s; ^.nast:= ; := ; Close(f); {rzyisz do ola s wskazywanego rzez łańcuch s} {wstaw element} {na zątek listy } {zamknij lik} Każda nowa wczytana linia tekstu zostaje wstawiona na zątek listy. W wyniku tej oeracji uzyskujemy strukturę listową zawierająca w ierwszym elemencie ostatnią linię tekstu znajdującego się w liku, w drugim rzedostatnią it. Wystarczy teraz wyisać kolejne elementy listy do liku lik.wyj, aby nasze zadanie zostało omyślnie zakończone. Przeglądanie listy Zmienna rzechowuje adres ierwszego elementu listy w amięci. Nie możemy modyfikować jej wartości, gdyż wiązałoby się to z utratą informacji na temat ołożenia ierwszego elementu, a co z tym się wiąże również ozostałej części listy. Wrowadźmy więc zmienną omocniczą tyu PElem (wskaźnik do TElem) i z jej omocą dokonajmy rzeglądu elementów listy. Przeglądanie listy będzie rzebiegać w nastęujących etaach: a) zmienna wskazuje na zątek listy (rys. 5a); := ; b) wyisz ole s zmiennej wskazywanej rzez ; WriteLn(^.s); 5

c) rzejdź do kolejnego elementu (rys 5b); := ^.nast; d) owtarzaj unkt b), doóki nie osiągniesz końca listy (sygnalizowane rzez wartość nil). a) b) Rys. 5. Przeglądanie listy jednokierunkowej Zatem cała rocedura wyisywania listy do liku będzie wyglądać nastęująco: rocedure WyiszListe; var : PElem; {wskaźnik omocniczy} f: text; {zmienna rerezentującą lik tekstowy} Assign(f,'lik.wej'); {otworzenie liku} Rewrite(f); {do zaisu} :=; {wskazanie rzez while <>nil do WriteLn(f,^.linia); :=^.nast; Close(f); na zątek listy } {doóki nie został osiągnięty koniec listy} {wyisz linię tekstu do liku} {rzejdź do nastęnego elementu} {zamknij lik} 6

Usuwanie listy Dodając nowe elementy do listy zmuszeni byliśmy do dynamicznego rzydzielania im amięci rzy każdorazowym utworzeniu nowego elementu za omocą oeratora new. Przed zakończeniem działania rogramu obowiązkiem rogramisty jest zwolnienie urzednio rzydzielonego obszaru amięci. Do tego celu użyjemy standardowej rocedury disose. Zauważmy, że nie wolno nam bezośrednio usunąć zątkowego elementu listy, wskazywanego rzez, gdyż w takim wyadku utracilibyśmy wskaźniki do ozostałej części listy. Wykorzystamy zmienną omocniczą tyu PElem, aby beziecznie usunąć element z listy. Cała oeracja będzie miała nastęujący rzebieg: a) zmienna wskazuje na zątek listy (rys. 6a); := ; b) wskazuje na element nastęny (rys 6b); := ^.nast; c) usuń beziecznie element (rys 6c); disose (); d) owtarzaj unkt a), doóki nie osiągniesz końca listy (sygnalizowane rzez wartość nil). a) b) c) Rys. 6. Usuwanie elementu z listy jednokierunkowej 7

Prześledźmy treść rocedury usuwającą wszystkie elementy listy z amięci: rocedure UsunListe; var : PElem; wskaźnik omocniczy} while <>Nil do :=; :=^.nast; {doóki nie został osiągnięty koniec listy} { wskazuje na zątek listy} {rzejdź do nastęnego elementu} disose(); {usun element } Treść rogramu Główna część rogramu ma za zadanie wyłącznie wywołanie każdej z zadeklarowanych rzez nas rocedur: UtworzListe; WyiszListe; UsunListe; ReadLn; end. Zauważmy, że zadeklarowanie ola tyu string jest osunięciem dalece nieekonomicznym, gdyż każda linia tekstu zawiera różną ilość tekstu, rzy tym niezwykle rzadko (o ile w ogóle) osiąga maksymalną długość. Można zatem rozważyć również dynamiczny rzydział amięci dla oszczególnych łańcuchów za omocą rocedur GetMem oraz FreeMem. Ta modyfikację ozostawiam czytelnikowi. 8