Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
Dynamiczne struktury danych
AiSD_W4 Dynamiczne struktury danych dr inż. Kustra Piotr Opracowanie: Anna Adrian oraz Kustra Piotr
2
… Tablice dynamiczne t2 t1 nElem
program DynamicVec; var t1 : array of integer; t2 : array [1..10] of integer; nElem: integer; BEGIN read(nElem); write('Ile elementów? ', nElem); setlength(t1, nElem); for i:=1 to nElem do begin t1[i]:=0; end; end. t2 t1 … nElem
3
Macierz dynamiczna sizeY sizeX
program DynamicMatrix; var sizeX, sizeY, i, j:integer; m:array of array of integer; begin size:=15; SetLength(m, sizeX, sizeY); for i:=0 to sizeX-1 do for j:=0 to sizeY-1 do m[i,j]:=1; end; readln(); end. sizeY sizeX
4
Zbiory dynamiczne Zbiory
– w matematyce pojęcie fundamentalne, niezmienne; - w informatyce zbiory mogą być zmieniane w wyniku działania algorytmów (powiększać, zmniejszać, albo zmieniać w czasie) – stąd ich nazwa zbiory dynamiczne. Zbiór dynamiczny do którego można dodawać (wstawiać) elementy, usuwać elementy ze zbioru i sprawdzać czy element należy do zbioru nazywane są słownikami. Metoda realizacji zbiorów dynamicznych zależy od operacji, które na konkretnym zbiorze mogą być wykonane.
5
Elementy zbioru dynamicznego
Każdy element zbioru dynamicznego jest reprezentowany przez obiekt, którego pola można odczytać lub modyfikować, jeśli mamy wskaźnik tego obiektu. W pewnych rodzajach zbiorów dynamicznych wyróżnione jest jedno z pól każdego elementu i nazywane kluczem (key) obiektu. Jeśli każdy element zbioru dynamicznego ma własny unikalny (niepowtarzalny) klucz, wtedy zwykle taki zbiór traktujemy jako zbiór kluczy. W niektórych implementacjach zbiorów dynamicznych zakłada się, że zbiór kluczy jest liniowo uporządkowany Obiekt może zawierać też inne dane (dodatkowe dane) zawarte w innych polach, jednak one nie wpływają na realizację zbioru Istnieje możliwość występowania w obiekcie pól zawierających wartości zmieniające się przez operacje na zbiorze (np. wskaźniki do innych obiektów w zbiorze)
6
Operacje na zbiorach dynamicznych
Wyróżnia się dwie grupy operacji na zbiorach dynamicznych, są to: Zapytania– pozwalające uzyskać pewne informacje na temat zbioru: SEARCH, MINIMUM, MAXIMUM, SUCCESSOR(następca), PREDECESSOR(poprzednik) Operacje modyfikujące– umożliwiające wprowadzanie zmian w zbiorze dynamicznym : INSERT i DELETE. Wymienione operacje uznawane są jako typowe. W konkretnych implementacjach zbiorów dynamicznych zwykle znajdują zastosowanie tylko niektóre z nich.
7
Operacje na zbiorach dynamicznych Zapytania
SEARCH(S,k) - dla danego zbioru S i klucza k zwraca wskaźnik x do takiego obiektu w zbiorze S, dla którego key[x]=k albo NIL- gdy w zbiorze S nie znaleziono żadnego obiektu spełniającego podany warunek. MINIMUM(S) – zwraca w wyniku element zbioru S o najmniej -szym kluczu; dotyczy zbiorów liniowo uporządkowanych. MAXIMUM(S) wskazuje element zbioru S o największym kluczu; dotyczy zbiorów liniowo uporządkowanych.
8
Operacje na zbiorach dynamicznych Zapytania
SUCCESSOR (S,x) - dla danego elementu x o kluczu należącym do uporządkowanego zbioru S daje w wyniku następnik elementu x w S, tj najmniejszy element ze zbioru S który jest większy od x. Jeśli x jest największym elementem w zbiorze S wynikiem jest stała NIL PREDECESSOR (S,x) dla danego elementu x o kluczu należącym do uporządkowanego zbioru S daje w wyniku poprzednik elementu x w S, tj największy element ze zbioru S który jest mniejszy od x. Jeśli x jest najmniejszym elementem w zbiorze S wynikiem jest stała NIL
9
Operacje na zbiorach dynamicznych Operacje modyfikujące
INSERT(S,x) – dodaje do zbioru S wskazany element x. Przy tej operacji zakłada się zwykle, że wcześniej zostały zainicjowane wartości wszystkich pól obiektu wskazanego przez x istotne dla realizacji zbioru S DELETE(S,x)- dla danego wskaźnika x do obiektu zawartego w zbiorze S usuwa ten element ze zbioru S. Warto zauważyć, że argumentem tej operacji jest wskaźnik do elementu x a nie wartość jego klucza. Czas wymagany do realizacji operacji na zbiorze wyrażany jest zwykle jako funkcja rozmiaru zbioru.
10
Elementarne dynamiczne struktury danych
Zbiory dynamiczne mogą być realizowane przez różne struktury danych. W dalszym ciągu wykładu przedstawiono podstawy realizacji elementarnych struktur danych, takich jak: Stosy Kolejki Listy Drzewa
11
Stosy i kolejki Stosy i kolejki są realizacją zbiorów dynamicznych w których element usuwany jest określony jednoznacznie: stos: strategia LIFO (last in first out) –najpóźniej dodany usuwany jest jako pierwszy kolejka: strategia FIFO (first in first out) _ najwcześniej usuwany jest element najstarszy Stosy i kolejki mogą być efektywnie implementowane na wiele sposobów
12
Stos Stos zawierający nie więcej niż n elementów można zaimplementować w n elementowej tablicy S[1..n] Atrybut top [S] oznacza numer ostatnio wstawionego elementu do stosu. Stos składa się z elementów: S[1..top[S]], gdzie S[1] jest elementem na dnie stosu S[top[S]] jest elementem na wierzchu stosu 1 2 3 4 5 6 7 S 15 9 top [S] = 4
13
Podstawowe operacje na stosie
Sprawdzam czy stos jest pusty: Stack-Empty(S) if top (S) =0 then return TRUE else return FALSE Jeśli top[S] =0 to stos jest pusty. Na próbę zdjęcia elementu ze stosu pustego powinien pojawić się komunikat o wystąpieniu błędu niedomiaru. Błąd przepełnienia występuje wtedy gdy top[S] > n
14
Podstawowe operacje na stosie Insert – PUSH
PUSH (S,x) top [S] top [S] +1 S[ top [S]] x PUSH (S,17) PUSH (S,3) 1 2 3 4 5 6 7 S 15 9 17 top [S] = 6
15
Podstawowe operacje na stosie Delete - POP
POP (S) If STACK-EMPTY (S) then error „niedomiar” else top [S] top [S] -1 return S[ top [S] +1] 1 2 3 4 5 6 7 S 15 9 17 top [S] = 5
16
Kolejki Kolejkę zawierającą nie więcej niż n elementów można zaimplementować w n elementowej tablicy Q[1..n] Atrybut head [Q] wskazuje głowę (początek) kolejki Atrybut tail[Q] wyznacza następną wolną pozycję na którą można wstawić do kolejki nowy element. Jeśli head [Q] = tail[Q] to kolejka jest pusta. Początkowo head [Q] = tail[Q] =1 Jeśli kolejka jest pusta i próbujemy usunąć z niej element występuje wtedy błąd niedomiaru Jeśli head [Q] = tail[Q] +1, to kolejka jest pełna i przy próbie wstawienia kolejnego elementu występuje błąd przepełnienia
17
Kolejki Kolejka zawiera 5 elementów na pozycjach Q [7..11]
2 3 4 5 6 7 8 9 10 11 12 Q 15 head [Q]=7 tail [Q] = 12 Kolejka zawiera 5 elementów na pozycjach Q [7..11] Elementy kolejki zajmują pozycje head [Q], head [Q]+1,……………, tail[Q]-1 Zakładamy, że Tablica Q jest cykliczna, tzn pozycja 1 jest bezpośrednim następnikiem pozycji n .
18
Podstawowe operacje na kolejkach ENQUEUE (Q,x)
Q [tail [Q]] x if tail [Q]=length [Q] then tail [Q] 1 else tail [Q] tail [Q] +1 ENQUEUE (Q,17); ENQUEUE (Q,3); ENQUEUE (Q,5) 1 2 3 4 5 6 7 8 9 10 11 12 Q 15 17 tail [Q] = 3 head [Q]=7
19
Podstawowe operacje na kolejkach DEQUEUE (Q)
DEQUEUE (Q,x) x Q [head[Q]] if head [Q]=length [Q] then head[Q] 1 else head[Q] head [Q] +1 return x DEQUEUE (Q); 1 2 3 4 5 6 7 8 9 10 11 12 Q 15 17 tail [Q] = 3 head [Q]=8
20
Kolejka dwustronna W stosach wstawianie i usuwanie elementów jest realizowane tylko na jednym końcu, na górze stosu. W kolejce dodajemy elementy na jednym końcu a usuwamy z drugiego końca. Kolejka dwustronna (dwukierunkowa) jest strukturą danych pozwalającą na wstawianie i usuwanie elementów na obu końcach kolejki. Napisać procedury służące do wstawiania elementów na obu końcach i do usuwania z obu końców kolejki zaimplementowanej w tablicy
21
Listy Lista z dowiązaniami jest prostą i elastyczną strukturą danych, służącą do reprezentowania zbiorów dynamicznych, umożliwiającą wykonanie wszystkich typowych operacji na zbiorach. Elementy listy ułożone są w porządku liniowym. Porządek określają wskaźniki związane z każdym elementem listy, a nie jak w tablicach, gdzie porządek jest wyznaczony przez indeksy.
22
Atrybuty listy Każdy element listy dwukierunkowej (doubly linked list) jest rekordem składającym się z trzech pól : key[x] –zawierającego klucz elementu x, prev[x]- wskazującego na poprzednika elementu x, Jeśli prev[x]=NIL to element x nie ma poprzednika, x jest pierwszym elementem listy, mówimy, że x jest wtedy głową (head) listy. Jeśli head[L] = NIL to lista jest pusta next[x] – wskazującego na następnika x na liście Jeśli next [x]=NIL to element x nie ma następnika , czyli x jest ostatnim elementem listy, nazywanym ogonem listy
23
Rodzaje list Lista jest jednokierunkowa (singly linked list) gdy pomijany jest wskaźnik prev Lista jest posortowana gdy kolejność elementów na liście jest zgodna z porządkiem na ich kluczach; - element o najmniejszym kluczu znajduje się w głowie, - element o największym kluczu w ogonie listy. W liście nieposortowanej kolejność elementów jest dowolna. W liście cyklicznej, elementy tworzą pierścień. Pole prev elementu w głowie wskazuje na ogon, a pole next w ogonie na głowę listy cyklicznej.
24
Operacje na listach - wyszukiwanie
Założenie: listy są dwukierunkowe, nieposortowane. Procedura LIST-SEARCH (L,k) wyznacza pierwszy element o kluczu k na liście L za pomocą prostego sortowania. Czas jej działania wynosi (n) LIST-SEARCH (L,k) x head[L] while x NIL i key[x] k do x next[x] return x Po wywołaniu procedury LIST-SEARCH (L,4) na liście otrzymamy wskaźnik do jej trzeciego elementu, a po wywołaniu LIST-SEARCH (L,7) otrzymamy NIL
25
Operacje na listach – wstawianie nowych elementów
Procedura LIST-INSERT(L,x) przyłącza element x, którego pole key zostało wcześniej zainicjowane, na początek listy. Czas działania procedury na liście o n elementach wynosi O(1) LIST-INSERT(L,x) next[x] head[L] if head[L] NIL then prev[head[L] ] x head[L] x prev[x] NIL Po wykonaniu procedury LIST-INSERT(L,x), gdzie key[x]=25 w głowie listy znajdzie się nowy rekord z kluczem 25 pole next zawiera wskaźnik do poprzedniej głowy z kluczem 9
26
Operacje na listach –usuwanie elementów z list z dowiązaniami
Wywołanie procedury LIST-DELETE (L,x) powoduje usunięcie elementu x z listy L. Wycinanie elementu z listy polega na modyfikacji odpowiednich wskaźników. Czas działania procedury na liście o n elementach wynosi O(1) ale pesymistyczny czas usuwania elementu o zadanym kluczu wynosi (n) ponieważ Najpierw musi zostać wywołana procedura LIST-SEARCH, aby wyznaczyć wskaźnik elementu x
27
Operacje na listach –usuwanie elementów z list z dowiązaniami
LIST-DELETE (L,x) if prev[x] NIL then next[ prev[x]] next[x] else head[L] next[x] if next[x] NIL then prev [next [x]] prev[x] Wynik wykonania operacji LIST-DELETE (L,x), gdzie x wskazuje na element o kluczu 4 z poprzedniej listy
28
Tablicowe reprezentacje struktur wskaźnikowych
Reprezentacja wielotablicowa Dana jest lista: Przedstawmy reprezentację tej listy za pomocą trzech tablic: Tablica key zawiera wartości kluczy znajdujących się na liście Tablice next i prev zawierają wskaźniki Wartości key[x], prev[x] i next[x] określają jeden element listy o indeksie x. Indeksy odgrywają rolę wskaźnika w tablicach key, next i prev
29
Tablicowa reprezentacja listy (danej)
W zmiennej L pamiętany jest numer pozycji (7) na której znajduje się głowa listy. Na liście klucz 4 znajduje się bezpośrednio za elementem o kluczu 16
30
Lista jednostronnie wiązana – implementacja wskaźnikowa
Definicja elementu listy info *next val: integer next: stos H NIL type stos = ^node; node=record val: integer; next: stos; end; 10 -6 12 H NIL
31
Dodawanie do stosu H pom x procedure PUSH (x:integer); NIL var
pom:^node; begin new(pom); pom^.val:=x; pom^.next:=head; head:=pom; end; H NIL x pom
32
Dodawanie do stosu H pom x1 x2 procedure PUSH (x:integer); var
pom:^node; begin new(pom); pom^.val:=x; pom^.next:=head; head:=pom; end; x1 H NIL x2 pom
33
Usuwanie ze stosu H pom 10 -6 12 procedure POP; var pom:^node; begin
if head <>NIL then pom:=head; head:= pom^.next; dispose(pom); end; 10 -6 12 H NIL pom
34
Przeglądanie listy jednostronnie wiązanej
procedure ShowList; var pom:^node; begin pom:=head; write('HEAD --> '); while (pom<>NIL) do write(pom^.val, '--> '); pom:=pom^.next; end; writeln ('NIL'); 10 -6 12 H NIL pom HEAD--> 10-->
35
Przeglądanie listy jednostronnie wiązanej
procedure ShowList; var pom:^node; begin pom:=head; write('HEAD --> '); while (pom<>NIL) do write(pom^.val, '--> '); pom:=pom^.next; end; writeln ('NIL'); 10 -6 12 H NIL pom HEAD--> 10--> -6-> 12-->
36
Przeglądanie listy jednostronnie wiązanej
procedure ShowList; var pom:^node; begin pom:=head; write('HEAD --> '); while (pom<>NIL) do write(pom^.val, '--> '); pom:=pom^.next; end; writeln ('NIL'); 10 -6 12 H NIL pom HEAD--> 10--> -6-> 12--> NIL
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.