lecture7 dynamic data struc

background image

Zajęcia nr 8/9

Struktury danych – dane dynamiczne

Algorytmy i struktury danych

Prowadzący:

dr hab.inż. ANDRZEJ WALCZAK,

prof.WAT

background image

2

Algorytmy i struktury danych, wykład 3

Wykład : Realizacje dynamicznych

struktur danych

Dynamiczne realizacje struktur listowych (definiowanie
elementu listy, dołączanie i usuwanie elementu listy,
wyszukiwanie elementu w liście, przestawianie
elementów w liście);

Dynamiczne realizacje struktur drzewiastych
(definiowanie elementu drzewa, dołączanie i usuwanie
elementu drzewa, wyszukiwanie elementu w drzewie);

Dynamiczne realizacje tablic;

background image

3

Algorytmy i struktury danych, wykład 3

Statyczna a dynamiczna struktura

danych

Statyczna struktura danych:

Posiada z góry ustalony rozmiar (bez możliwości jego
zmiany);

Jej deklaracja poprzedza uruchomienie głównej
procedury programu;

Liczba zmiennych o typie statycznych musi być z góry
znana;

Pamięć jest przydzielana na wstępie a oddawana po
zakończeniu programu;

background image

4

Algorytmy i struktury danych, wykład 3

Statyczna a dynamiczna struktura

danych

Dynamiczną strukturę danych odróżnia sposób przydziału

pamięci operacyjnej:

ilość wymaganej pamięci przez struktury danych nie

musi być znana przed uruchomieniem programu;

przydział pamięci następuje dynamicznie w czasie

realizacji odpowiedniej części programu;

po wykonaniu zadań struktury danych powinny być

usunięte a przydzielona pamięć dynamicznie

zwolniona;

zaleta tego podejścia:

możliwość dynamicznego tworzenia struktur danych o

różnych „kształtach”;

„brak” ograniczeń na wielkość struktury;

wada: złożone operacje dodawania i usuwania

elementów struktury;

background image

5

Algorytmy i struktury danych, wykład 3

Arytmetyka wskaźników –

przypomnienie

Utworzenie struktury dynamicznej możliwe jest
poprzez zastosowanie wskaźników, adresów,
referencji;

Czy potrafimy odróżnić pojęcie i właściwości:

zmiennej,

wskaźnika,

adresu,

referencji?

background image

6

Algorytmy i struktury danych, wykład 3

Arytmetyka wskaźników –

przypomnienie

Deklaracja zmiennej ‘var’ o typie ‘type’:

type var;

Przykład:

int x = 8;

Deklaracja zmiennej wskaźnikowej ‘name’ do typu ‘type’ :

type *name;

Przykład:

int *ip;

/*wskaźnik na typ integer*/

float *fp;

/*wskaźnik na typ float */

Przypisanie adresu zmiennej x do wskaźnika ip;

ip = &x;

& oznacza ‘adres’ i zwraca adres stojącej przy nim
operandy;

ip teraz wskazuje na x;

i
p
f
p

ip

8

X

background image

7

Algorytmy i struktury danych, wykład 3

Arytmetyka wskaźników –

przypomnienie

Pobranie wartości wskazywanej przez wskaźnik :

int y;

y = *ip;

y teraz posiada wartość równą x;

8

x

ip

Reprezentacja logiczna

600000

ip

8

x

500000

600000

Fizyczna reprezentacja w pamięci

background image

8

Algorytmy i struktury danych, wykład 3

Arytmetyka wskaźników –

przypomnienie

Przeanalizuj i wyjaśnij poniższy fragment kodu:

int x=1, y=2, z[10];
int *ip, *iq;

ip = &x;

y = *ip;

*ip = 0;

*ip += 1;
y = *ip+2;
ip = &z[0];
iq = ip;

/* ip wskazuje na x

*/

/* y = 1

*/

/* x przypisano 0

*/

/* x zwiększone o 1 */
/* y = 3

*/

/* ip wskazuje na z[0]

*/

/* iq wskazuje na z[0]

*/

background image

9

Algorytmy i struktury danych, wykład 3

Arytmetyka wskaźników –

przypomnienie

Przykład operacji dla typu prostego:

int *px;

px += 2;

px = (adres px) + 2 * rozmiar obiektu wskazywanego

przez px;

dla px równe jest 3000 i rozmiaru 4 dla int:

3000 + 2 * 4 = 3008;

Przykład dla tablicy:

int a[4];

int *pa;

pa = a; /* lub pa=&a[0]; */

pa ++;

/*pa wskazuje na a[1] */

pa =+ 2;

/*pa wskazuje na a[3] */

pa --; /*pa wskazuje na a[2] */

a[0] a[1] a[2] a[3]

3000 3004 3008 3012

pa

background image

10

Algorytmy i struktury danych, wykład 3

Dynamiczne zarządzanie pamięcią

operacyjną

Dynamiczny przydział pamięci (alokacja):

malloc() /* z biblioteki stdlib.h */

Przykład:

void * malloc(size_t size);

‘void’ pozwala na wskazanie danych dowolnego typu;

argumentem funkcji jest rozmiar przydzielanej pamięci;

pamięć przydzielana jest z obszaru zwanego kopcem;

sizeof() – operator do określenia wielkości pamięci:

sizeof(int) – zwróci rozmiar pamięci potrzebny dla
przechowania danych typu integer;

sizeof(struct node) – zwróci rozmiar pamięci potrzebny dla
przechowania danych typu zadeklarowanej struktury
‘node’;

background image

11

Algorytmy i struktury danych, wykład 3

Dynamiczne zarządzanie pamięcią –

polecenia

rekursywn

a

deklaracja

struktury

Przykład użycia malloc() i sizeof():

(1)

int x=1, y;

y = sizeof x;

lub y = sizeof (int);

(2)

struct node {

char data;
struct node *nextPtr };

struct node *newPtr;
newPtr = malloc(sizeof(struct node));

newPt
r

Dane

nextPtr

?

background image

12

Algorytmy i struktury danych, wykład 3

Dynamiczne zarządzanie pamięcią –

polecenia

Dynamiczne zwolnienie pamięci (na kopiec):

free()

/* z biblioteki stdlib.h */

Przykład:

struct node {

char data;
struct node *nextPtr };

struct node *newPtr;
newPtr = malloc(sizeof(struct node));

/* operacje na danych*/

free (newPtr);

background image

13

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Definiowanie elementu listy;

Dołączanie i usuwanie elementu listy;

Wyszukiwanie elementu w liście;

Przestawianie elementów w liście;

background image

14

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Model grafowy listy jednokierunkowej (dwukierunkowej)

e

d

1

d

2

d

3

d

n

e

d

1

d

2

d

3

d

n

background image

15

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Element listy zawiera:

Dane elementarne,

Odwzorowanie relacji następstwa – informacja o
dowiązaniu do innych elementów;

dane

dowiązanie

start

NULL

ogon

głowa

background image

16

Algorytmy i struktury danych, wykład 3

dane

elementar

ne

dowiązani

e do

kolejnego

elementu

Dynamiczne realizacje struktur

listowych

Deklaracja elementu listy:

struct Node {

char data;
struct Node *next;
};

typedef struct Node *NodePtr;

/* pomocniczy typ wskaźnikowy do struktury ‘Node’

*/

/* zmienna ‘start’ tego typu wskazywać będzie

głowę listy */

background image

17

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy
jednokierunkowej (1):

Cel:

Dodanie nowego elementu do listy;

Dane wejściowe:

Dowiązanie głowy listy ‘startPtr’;

Nowa dana elementarna;

background image

18

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy
jednokierunkowej (2):

Utwórz element i ustal dane elementarne;

Znajdź miejsce wstawienia elementu w
liście;

Wstaw element do listy:

Wstaw element jako pierwszy w liście;

(lub) Wstaw element we wskazane miejsce w
liście;

background image

19

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy
jednokierunkowej (3):

Utwórz element i ustal dane elementarne
int insert (NodePtr *startPtr, char nazwa)
{

Node *newPtr, *currPtr, *prevPtr;
int retcode=1;
/* Utwórz element Node */

newPtr = (Node *)malloc(sizeof(Node));

background image

20

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Schemat algorytmu cz.3

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

background image

21

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy jednokierunkowej (4):

Utwórz element i ustal dane elementarne
int insert (NodePtr *startPtr, char nazwa)

{
Node *newPtr, *currPtr, *prevPtr;

int retcode = 1;
/* Utwórz element Node */

newPtr = (Node *)malloc(sizeof(Node));

if (newPtr == NULL) /* weryfikacja przydzielonej pamięci*/

retcode = 0;
else

{ /* Ustal dane elementarne w Node */

newPtr -> data = nazwa;
newPtr -> next = NULL;

/* Inicjalizacja wskaźników pomocniczych */

currPtr = *startPtr; /* ustaw wskaźnik na głowę listy */

prevPtr = NULL;

background image

22

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Schemat działania algorytmu cz.4

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NUL
L

background image

23

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy jednokierunkowej
(5):

Utwórz element i ustal dane elementarne

Znajdź miejsce wstawienia elementu w liście

Dopóki currPtr jest różny od NULL oraz dane elementu
wstawianego są ‘większe’ od currPtr->data:

• Ustaw prevPtr na currPtr;
• Przesuń currPtr na następny element listy;


/* Znajdź miejsce wstawienia */
while ((currPtr != NULL) && (nazwa > currPtr->data))
{
prevPtr = currPtr;
currPtr = currPtr -> next;
}

background image

24

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Schemat algorytmu cz.5

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

C

NUL
L

background image

25

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy jednokierunkowej
(6):

Utwórz element i ustal dane elementarne

Znajdź miejsce wstawienia elementu w liście

Zainicjalizuj currPtr na start listy a prevPtr na NULL;

Dopóki currPtr jest różny od NULL i wartość wstawiana jest
większa od currPtr->data:

• Ustaw prevPtr na currPtr;
• Przesuń currPtr na następny element listy;

Wstaw element do listy:

Wstaw element jako pierwszy w liście:

• Ustaw pole next elementu wstawianego na pierwszy element listy;
• Ustaw wskaźnik do listy na element wstawiony;

(lub) Wstaw element we wskazane miejsce w liście:

• Ustaw pole next elementu prevPtr na element wstawiany;
• Ustaw pole next elementu wstawianego na element currPtr;

background image

26

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy
jednokierunkowej (7):

/* Wstaw element */
if (prevPtr == NULL)
/* Wstaw element jako pierwszy w liście */
{

newPtr -> next = *startPtr;
*startPtr = newPtr;

}

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NUL
L

startPtr

newPtr

prevPtr

D

currPtr

C

A

B

NULL

NUL
L

background image

27

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm dołączania elementu do listy
jednokierunkowej (8):

/* Wstaw element */

/* Wstaw element w miejsce między prevPtr a currPtr
*/
else

{

newPtr->next = currPtr;
prevPtr->next = newPtr;
}
retcode = 1;
}
return retcode;

}

background image

28

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Schemat algorytmu cz.8

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NUL
L

startPtr

newPtr

currPtr

D

prevPtr

A

B

C

NUL
L

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

C

NUL
L

background image

29

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Uwagi do dołączania elementu do listy
dwukierunkowej
:

każdy element posiada dodatkowe pole (dowiązanie)
prev, które dla pierwszego elementu listy jest równe
NULL;

lista może być przeglądana w obydwu kierunkach;

często pamięta się dowiązania do pierwszego i
ostatniego elementu;

należy zawsze uaktualniać dowiązania w obydwu
kierunkach (wartości czterech pól);

Czy potrafisz dostosować zaprezentowany

algorytm do list dwukierunkowych?

background image

30

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Uwagi do dołączania elementu do listy cyklicznej:

brak dowiązań wskazujących na NULL;

w liście jednoelementowej dowiązania wskazują na
ten sam element;

aby uniknąć pętli nieskończonej podczas
przeglądania listy, należy zastosować ‘strażnika’ –
dowiązanie do pierwszego elementu (umownego);

Czy potrafisz dostosować zaprezentowany

algorytm do list cyklicznych?

background image

31

Algorytmy i struktury danych, wykład 3

Przykład dołączania

elementu do listy

#include "lista.h"

void LISTA::dorzuc1(int x) // dolaczamy rekord na

koniec listy

{ // (ver.1 - bez "sortowania")

ELEMENT *q=new ELEMENT;

q->wartosc=x;

q->nastepny=NULL;

if (inf.glowa==NULL) // lista pusta

inf.glowa=inf.ogon=q;

else // cos jest w liscie

{

(inf.ogon)->nastepny=q;

inf.ogon=q;

}}

background image

32

Algorytmy i struktury danych, wykład 3

Przykład dołączania

elementu do listy

Jak działa zaprezentowany kod?

W przypadku listy pustej obydwa pola początkowe
struktury lista są inicjowane wskaźnikiem na nowo
powstały element

Jeśli lista nie jest pusta nowy element zostaje podpięty do
końca listy stając się jej ogonem a element pierwszy
zapewnia relację wejścia w listę

Oczywiście można pierwszy element ustawiać jako
początek listy czyli głowa. Założeniem było ze przydział
pamięci na wskaźnik nastąpi i będzie różny od zera

Zaprezentujemy realizacje połączenia dwóch zadanych
list utworzonych wg pliku lista.h o kodzie napisanym w
C++ z elementami programowania obiektowego. Na tych
listach wykonanych będzie kilka operacji szukania,
dopisywania, usuwania.

background image

33

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm szukania elementu w liście
jednokierunkowej (1):

Cel:

Wyszukanie elementu w liście;

Dane wejściowe:

Dowiązanie głowy listy ‘startPtr’;

Kryterium poszukiwania, np. wartość danej
elementarnej;

Uwagi:

W skrajnym przypadku należy przejrzeć wszystkie
elementy (złożoność O(n));

background image

34

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm szukania elementu w liście
jednokierunkowej (2):

Rozpocznij od pierwszego elementu listy;

Dopóki aktualny element listy jest różny od NULL oraz
dane szukane są różne od danych aktualnego
elementu, to przemieść się do następnego elementu
listy;

Daj dowiązanie do aktualnego elementu;

background image

35

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm szukania elementu w liście
jednokierunkowej (3):

Node *Find (NodePtr *startPtr, char nazwa)
{

NodePtr currPtr = *startPtr; /* pierwszy element
listy */
while ((currPtr != NULL) && (currPtr -> data !=
nazwa
))

currPtr = currPtr -> next;

return currPtr;

}

background image

36

Algorytmy i struktury danych, wykład 3

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NUL
L

startPtr

D

A

B

C

NUL
L

Dynamiczne realizacje struktur

listowych

Algorytm szukania elementu w liście
jednokierunkowej (4):

Przykład:
Node *ele = Find (startPtr, ‘C’);

currPtr

Nazwa szukana: C

currPtr: startPtr

currPtr -> data: A

background image

37

Algorytmy i struktury danych, wykład 3

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NUL
L

startPtr

D

A

B

C

NUL
L

Dynamiczne realizacje struktur

listowych

Algorytm szukania elementu w liście
jednokierunkowej (5):

Przykład:
Node *ele = Find (startPtr, ‘C’);

currPtr

Nazwa szukana: C

currPtr: currPtr -> next

currPtr -> data: B

background image

38

Algorytmy i struktury danych, wykład 3

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NUL
L

startPtr

D

A

B

C

NUL
L

Dynamiczne realizacje struktur

listowych

Algorytm szukania elementu w liście
jednokierunkowej (6):

Przykład:
Node *ele = Find (startPtr, ‘C’);

currPtr

Nazwa szukana: C

currPtr: currPtr -> next

currPtr -> data: C

background image

39

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm usuwania elementu z listy
jednokierunkowej (1):

Cel:

Usunięcie elementu z listy;

Dane wejściowe:

Dowiązanie głowy listy ‘startPtr’;

Opis elementu, np. wartość danej elementarnej;

background image

40

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm usuwania elementu z listy
jednokierunkowej (2):

Jeżeli dane są zgodne z danymi pierwszego elementu
listy

Usuń pierwszy element listy;

W p.p. znajdź element do usunięcia w liście;

Jeżeli nie znaleziono elementu, generuj komunikat;

W p.p. usuń znaleziony element;

background image

41

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm usuwania elementu z listy jednokierunkowej (3):

Jeżeli dane są zgodne z danymi pierwszego elementu listy

Usuń pierwszy element listy;

int delete (NodePtr *startPtr, char nazwa)

{

NodePtr prevPtr, currPtr, tempPtr;

int retcode;
if (*startPtr == NULL)

/* Lista pusta */

retcode = 0;

else

{

if (nazwa == (*startPtr)->data) /* Usuń pierwszy element

listy */
{
tempPtr = *startPtr;

*startPtr = (*startPtr)->next;

free (tempPtr);

retcode = 1;

}

background image

42

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm usuwania elementu z listy jednokierunkowej

(4):

Jeżeli dane są zgodne z danymi pierwszego elementu

listy

Usuń pierwszy element listy;

W p.p. znajdź w liście element do usunięcia:


else

{ /* znajdź w liście element do usunięcia */

prevPtr = *startPtr;

/* początek listy */

currPtr = (*startPtr)->next; /* drugi element*/

while (currPtr != NULL && currPtr -> data != nazwa)

{

prevPtr = currPtr;

currPtr = currPtr -> next;

}

background image

43

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm usuwania elementu z listy jednokierunkowej (5):

Jeżeli dane są zgodne z danymi pierwszego elementu listy

Usuń pierwszy element listy;

W p.p. znajdź element do usunięcia w liście:

Jeżeli nie znaleziono elementu, generuj komunikat;

W p.p. usuń znaleziony element;


if (currPtr == NULL)

retcode = 0; /* node not found */

else
{ /* Usuń znaleziony element */

tempPtr = currPtr;

prevPtr->next = currPtr->next;

free (tempPtr);

retcode = 1;

} } }

return retcode;
}

background image

44

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

listowych

Algorytm usuwania elementu z listy
jednokierunkowej (6):

A

startPtr

B

C

Przed
usunięciem:

NULL

A

startPtr

B

C

Po usunięciu:

NULL

background image

45

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Definiowanie elementu drzewa;

Dołączanie i usuwanie elementu drzewa;

Wyszukiwanie elementu w drzewie;

background image

46

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Drzewiastą strukturą danych nazywamy strukturę
danych

S=(D, R, e)

, w której relacja porządkująca

N

opisuje kolejne, rekurencyjne powiązania pomiędzy
danymi elementarnymi drzewa, tworzącymi kolejne
„poddrzewa”.

Przykład struktury drzewiastej

Uniwersytet

Wydział

Wydział

Wydział

Wydział

Instytut

Instytut

Instytut

Instytut

Instytut

background image

47

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Istnieje wiele sytuacji w których przetwarzane
informacje

mają strukturę hierarchiczna lub zagnieżdżoną, jak:
drzewo

genealogiczne lub diagram struktury organizacyjnej.

Abstrakcje modelującą strukturę hierarchiczną
nazywamy

drzewem – jest to jeden z najbardziej podstawowych

modeli

danych w informatyce.

background image

48

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Kiedy mówimy o reprezentowaniu drzew, w pierwszej
kolejności mamy na myśli sposób reprezentowania węzłów.

Różnica miedzy reprezentacjami drzew dotyczy miejsca w
pamięci komputera gdzie przechowywana jest struktura
zawierająca węzły.

W języku C możemy stworzyć przestrzeń dla struktur
reprezentujących wierzchołki za pomocą funkcji

malloc

ze

standartowej biblioteki

stdhlib.h

, co powoduje,

ż

e do

umieszczonych w pamięci węzłów mamy dostęp tylko za
pomocą wskaźników. Rozwiązaniem alternatywnym jest
stworzenie tablicy struktur i wykorzystanie jej elementów
do reprezentowania węzłów. Możemy uzyskać dostęp do
węzłów nie wykorzystując ścieżek w drzewie. Wadą jest z
góry określony rozmiar tablicy (musi istnieć ograniczenie
maksymalnego rozmiaru drzewa).

background image

49

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Drzewo binarne (dwójkowe):

Drzewo o stopniu 2 (każdy węzeł ma co najwyżej
dwóch następników – potomków: lewego i
prawego);

Ostatnimi potomkami są liście (elementy, które nie
mają potomków);

e

d1

d2

d3

d4

d5

d6

poziom 1

poziom 2

poziom 3

Czy drzewo z jednego z poprzednich slajdów

(Uniwersytet) jest drzewem binarnym?

background image

50

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Zupełne drzewo binarne (dwójkowe):

Każdy węzeł, z wyjątkiem liści, ma dokładnie dwóch

potomków;

Drzewo poszukiwań binarnych (BST):

Dla każdego węzła (nie liścia) wszystkie wartości

przechowywane w lewym poddrzewie są mniejsze od

jego wartości oraz przeciwnie dla drzewa prawego;

Drzewo AVL (1962 – Adelson-Velskii, Landis)

Drzewo BST jest drzewem AVL wtedy, kiedy dla każdego

wierzchołka wysokości dwóch jego poddrzew różnią się o

co najwyżej 1 poziom;

Kopiec

Wartości przechowywane w potomkach każdego węzła są

mniejsze od wartości węźle;

Drzewo jest szczelnie wypełniane od lewego poddrzewa;

Liście leżą na co najwyżej dwóch sąsiednich poziomach;

background image

51

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Jednym z najprostszych sposobów reprezentowania drzewa jest
wykorzystanie dla każdego węzła struktury składającej się z
pola lub pól reprezentujących etykietę oraz tablicy wskaźników
do dzieci tego węzła.

typedef struct NODE *pNODE

struct NODE{

int info;

pNODE children[BF];

};

Info

reprezentuje

etykietę węzła

. Stała

bf

jest

rozmiarem

tablicy

wskaźników

. Reprezentuje maksymalna liczbę dzieci

dowolnego węzła, czyli

czynnik rozgałęzienia

(ang.

branching

factor

). i-ty element tablicy reprezentującej węzeł zawiera

wskaźnik do i-tego dziecka tego węzła. Brakujące połączenia
możemy reprezentować za pomocą wskaźnika pustego

NULL

.

inf
o

p

0

p

1

.......... p

bf-1

background image

52

Algorytmy i struktury danych, wykład 3

Zestawienie reprezentacji drzew

Reprezentacja oparta na tablicy wskaźników

umożliwia nam dostęp do -tego dziecka dowolnego
węzła w czasie O(1). Taka reprezentacja wiąże się
jednak ze znacznym marnotrawstwem przestrzeni
pamięciowej, jeśli tylko kilka węzłów ma wiele dzieci.
W takim wypadku większość wskaźników w tablicy

children

będzie równa

NULL

.

Reprezentacja skrajnie lewy potomek-prawy element

siostrzany

wymaga mniejszej przestrzeni

pamięciowej. Nie wymaga również istnienia
maksymalnego czynnika rozgałęzienie węzłów.
Możemy reprezentować węzły z dowolna wartością
tego czynnika, nie modyfikując jednocześnie
struktury danych.

background image

53

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Element drzewa zawiera:

Dane elementarne,

Realizację relacji następstwa – dowiązania do
następników;

Dane

Dowiązanie na

prawego

potomka

Dowiązanie na

lewego potomka

Korzeń

Liść

Potomek

Przodek

background image

54

Algorytmy i struktury danych, wykład 3

dane

elementar

ne

dowiązani

e do

prawego

potomka

dowiązani

e do

lewego

potomka

Dynamiczne realizacje struktur

drzewiastych

Deklaracja elementu drzewa binarnego:

struct Node {
int

data;

struct Node *llink;
struct Node *rlink;
};

typedef struct Node *NodePtr;

/* pomocniczy typ wskaźnikowy do struktury ‘Node’ */

/* zmienna ‘start’ tego typu wskazywać będzie korzeń
*/

background image

55

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Podstawowe operacje na drzewach binarnych:

szukanie elementu w drzewie,

przeglądanie drzewa;

dołączanie elementu do drzewa,

usuwanie elementu z drzewa,

Uwaga:

Operacje te często są realizowane
rekurencyjnie;

background image

56

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm szukania elementu w drzewie binarnym (1):

Cel:

uzyskanie dowiązania do węzła;

można je interpretować jako identyfikację węzła;

Dane wejściowe:

Dowiązanie do korzenia drzewa ‘Root’;

Kryterium poszukiwania, np. wartość danej
elementarnej;

Uwagi:

kolejność przeszukiwania dowolna – w skrajnym
przypadku należy przejrzeć wszystkie węzły w drzewie
(złożoność O(n));

stosowane rozwiązania: pętla lub rekurencja;

background image

57

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm szukania elementu w drzewie binarnym (2):

Ustaw aktualne dowiązanie na korzeń drzewa;

Dopóki aktualne dowiązanie jest różne od NULL:

Jeżeli wartość szukana jest mniejsza od danej
aktualnego węzła, to szukaj w jego lewym poddrzewie;

Jeżeli wartość szukana jest większa od danej aktualnego
węzła, to szukaj w jego prawym poddrzewie;

Jeżeli wartość szukana jest równa danej aktualnego
węzła, to koniec – daj dowiązanie do węzła;

background image

58

Algorytmy i struktury danych, wykład 3

przejście

do lewego

poddrzew

a

przejście

do

prawego

poddrzew

a

Dynamiczne realizacje struktur

drzewiastych

Algorytm szukania elementu w drzewie binarnym (3):

Wersja procedury z pętlą:
NodePtr find (int inValue, NodePtr node)
{

while (node) {

if (inValue == node -> data)
return node;
else if (inValue < node -> data)
node = node -> llink;
else if (inValue > node -> data)
node = node -> rlink;

return NULL;

}

background image

59

Algorytmy i struktury danych, wykład 3

wywołanie

procedury

dla

lewego

poddrzew

a

wywołanie

procedury

dla

prawego

poddrzew

a

Dynamiczne realizacje struktur

drzewiastych

Algorytm szukania elementu w drzewie binarnym (4):

Wersja procedury rekurencyjnej:
NodePtr find (int inValue, NodePtr node)
{

if (node) {

if (inValue == node -> data)
return node;
else if (inValue < node -> data)
return find ( inValue, node > llink);
else if (inValue > node -> data)
return find ( inValue, node > rlink);

else return NULL;

}

background image

60

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego (1):

Cel:

jednokrotne „odwiedzenie” każdego elementu
drzewa;

można je interpretować jako umieszczenie wszystkich
węzłów w jednej linii – linearyzacja drzewa;

Dane wejściowe:

Dowiązanie do korzenia drzewa ‘Root’;

Uwagi:

kolejność przejścia dowolna – liczba możliwych
ścieżek w drzewie o n węzłach wynosi n!
(permutacja?, prawda czy fałsz???);

najczęściej stosowane sposoby: wszerz i w głąb;

background image

61

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(2):

Wersja „inorder” – LVR (porządek symetryczny)

Przejście do lewego poddrzewa (L);

Odwiedzenie węzła (V);

Przejście do prawego poddrzewa (R);

Wersja „preorder” – VLR (porządek prosty)

Odwiedzenie węzła (V);

Przejście do lewego poddrzewa (L);

Przejście do prawego poddrzewa (R);

Wersja „postorder” – LRV (porządek odwrotny)

Przejście do lewego poddrzewa (L);

Przejście do prawego poddrzewa (R);

Odwiedzenie węzła (V);

background image

62

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb (3):

Wersja procedury „inorder” – LVR

porządek symetryczny (lewe-korzeń-prawe)

void inorder (NodePtr node)
{

if (node)

{
inorder (node -> llink);
visit (node);
inorder (node -> rlink);
}
}

background image

63

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb (4):

Wersja procedury „preorder” – VLR

porządek prosty (korzeń-lewe-prawe)

void preorder (NodePtr node)
{

if (node)

{
visit (node);
preorder (node -> llink);
preorder (node -> rlink);
}
}

background image

64

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb (5):

Wersja procedury „postorder” – LRV

porządek odwrotny (lewe-prawe-korzeń)

void postorder (NodePtr node)
{

if (node)

{
postorder (node -> llink);
postorder (node -> rlink);
visit (node);
}
}

background image

65

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(6):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik:

background image

66

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(7):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik:

background image

67

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(8):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik:

background image

68

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(9):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9

background image

69

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(10):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9

background image

70

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(11):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9

background image

71

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(12):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9, 11

background image

72

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(13):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9, 11

background image

73

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(14):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9, 11, 15

background image

74

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(15):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9, 11, 15

background image

75

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(16):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9, 11, 15

background image

76

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(17):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9, 11, 15,
28

background image

77

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm przeglądanie drzewa binarnego w głąb
(18):

Przykład dla procedury „inorder” – LVR

1
5

9

2
8

NULL

NULL

NULL

1
1

NULL

NULL

Root

inorder (node ->
llink);
visit (node);
inorder (node ->
rlink);

Wynik: 9, 11, 15,
28

background image

78

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa
binarnego (1):

Cel:

dodanie nowego elementu do drzewa;

Dane wejściowe:

Dowiązanie do korzenia drzewa ‘Root’;

Nowa dana elementarna;

background image

79

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa binarnego
(2):

Utwórz element i ustal dane elementarne;

Znajdź miejsce wstawienia elementu w drzewie;

Wstaw element do drzewa:

Wstaw element jako pierwszy w drzewie;

(lub) Wstaw element we wskazane miejsce w drzewie;

background image

80

Algorytmy i struktury danych, wykład 3

rekurenc

ja

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa binarnego (3):

void Insert (int inValue, NodePtr &next) {
if (next == NULL ) {
next = (Node *)malloc(sizeof(Node));

next -> llink = NULL;

next -> rlink = NULL;
next -> data = inValue;
}
else if ( inValue < next -> data )
Insert( inValue, next -> llink ) ;
else if ( inValue > next -> data )
Insert( inValue, next -> rlink );
}

background image

81

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa binarnego
(4):

Wstawienie do drzewa elementu z wartością ’11’;

Insert ( 11, Root);

1
5

9

2
8

Root

NULL

NULL

NULL

NULL

inValue = 11

background image

82

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa binarnego
(5):

Dopóki (inValue < next -> data)

Insert ( 11, next -> llink);

1
5

9

2
8

next

NULL

NULL

NULL

NULL

inValue = 11

background image

83

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa binarnego
(6):

Dopóki (inValue > next -> data)

Insert ( 11, next -> rlink);

1
5

9

2
8

next

NULL

NULL

NULL

NULL

inValue = 11

background image

84

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa binarnego

(7):

if (next == NULL ) {

next = (Node *)malloc(sizeof(Node));

next -> llink = NULL;

next -> rlink = NULL;

next -> data = inValue;

}

1
5

9

2
8

next

NULL

NULL

NULL

NULL

inValue = 11

background image

85

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm dołączania elementu do drzewa binarnego
(8):

Drzewo po wstawieniu elementu z wartością ’11’;

1
5

9

2
8

next

NULL

NULL

NULL

1
1

NULL

NULL

Root

inValue = 11

background image

86

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm usuwania elementu z drzewa
binarnego (1):

Cel:

Usunięcie węzła z drzewa;

Dane wejściowe:

Dowiązanie do korzenia drzewa ‘Root’;

Opis elementu usuwanego, np. wartość danej
elementarnej;

Uwagi:

Przypadek 1: węzeł jest liściem;

Przypadek 2: węzeł ma jednego potomka;

Przypadek 3: węzeł ma dwóch potomków;

background image

87

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm usuwania elementu z drzewa binarnego (2):

Przypadek 1: węzeł jest liściem:

Znajdź element w drzewie;

Usuń węzeł z drzewa;

1
5

9

2
8

NULL

1
5

2
8

NULL

7

9

NULL

11

11

25

25

background image

88

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm usuwania elementu z drzewa binarnego (3):

Przypadek 2: węzeł ma jednego potomka:

Znajdź element w drzewie;

Usuń węzeł z drzewa;

Zastąp węzeł usunięty jego potomkiem (zmiana
dowiązania w przodku węzła usuwanego)

1
5

9

2
8

NULL

1
5

2
5

NULL

NULL

7

7

11

11

7

25

background image

89

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm usuwania elementu z drzewa binarnego (4):

Przypadek 3: węzeł ma dwóch potomków:

Znajdź element w drzewie;

Usuń węzeł z drzewa;

Zastąp węzeł usunięty: najmniejszym z prawego
poddrzewa lub największym z lewego poddrzewa;

1
5

9

2
8

NULL

7

11

25

background image

90

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm usuwania elementu z drzewa binarnego (5):

Przypadek 3: węzeł ma dwóch potomków:

Wersja z przesunięciem najmniejszego elementu z
prawego poddrzewa (skrajnie lewy wierzchołek tego
poddrzewa);

1
5

9

2
8

NULL

7

2
5

9

7

11

25

11

28

NULL

NULL

background image

91

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm usuwania elementu z drzewa binarnego (6):

Przypadek 3: węzeł ma dwóch potomków:

Wersja z usunięciem największego elementu z lewego
poddrzewa (skrajnie prawy wierzchołek);

1
5

9

2
8

NULL

7

1
1

9

7

11

25

28

NULL

25

NULL

background image

92

Algorytmy i struktury danych, wykład 3

Dynamiczne realizacje struktur

drzewiastych

Algorytm usuwania elementu z drzewa binarnego (7):

Jeżeli w „Przypadku 3” przesuwany:

skrajnie prawy węzeł (największy element) z lewego
poddrzewa posiada potomka lewego;

skrajnie lewy węzeł (najmniejszy element) z prawego
poddrzewa posiada potomka prawego;

to należy zastosować dla węzła przesuwanego
dodatkowo algorytm usuwania z „Przypadku 2”
(usuwanie węzła z jednym potomkiem);

Inne rozwiązanie dla operacji usuwania zobaczymy na
wykładzie dotyczącym działań na rodzajach drzew
binarnych;

background image

93

Algorytmy i struktury danych, wykład 3

Podsumowanie

Omówiliśmy podstawowe zagadnienia związane ze
strukturami danych: listy i drzewa;

Przestudiuj jeszcze raz poszczególne algorytmy (ze
szczególną uwagą usuwanie elementów);

Spróbuj dokonać modyfikacji w kodzie prezentowanych
procedur dla list i drzew;

Zauważ, że podane algorytmy tworzą pewien zestaw
standardu postępowania ze strukturami danych i
szczegółowe postaci algorytmów zależą tylko od
analizowanej struktury danych.

Dziękuję za uwagę


Document Outline


Wyszukiwarka

Podobne podstrony:
lecture 13 spc and data integration handouts
lecture5 6 data structure 2
lecture5 6 data structure
Lecture 10 DynamicDataStructures
IR Lecture1
uml LECTURE
lecture3 complexity introduction
Dynamika1
Techniki wywierania wplywu oparte na dynamice interakcji
196 Capital structure Intro lecture 1id 18514 ppt
Analiza dynamiczna chodu w fazie podporu
Lecture VIII Morphology
benzen lecture
dynamika bryly sztywnej(1)

więcej podobnych podstron