background image

 

 

Podstawy 
programowania II

Wykład 5: Dynamiczne struktury danych

Zachodniopomorska Szkoła Biznesu

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Struktury danych

Dane - model rzeczywistości

Złożoność i wielość danych opisujących dany problem

Potrzeba organizacji danych w logiczne całości zwane 
strukturami danych

grupowanie danych w sposób odzwierciedlający 
rzeczywiste związki pomiędzy danymi

opis podobnych obiektów za pomocą jednakowych 
zestawów danych

Korzyści płynące z budowy struktur danych

ułatwienie projektowania oprogramowania

możliwość automatyzacji przetwarzania danych

efektywniejsze zarządzanie pamięcią

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Statyczne struktury danych

W przypadku problemów prostych i ograniczonych pod 
względem liczby przetwarzanych danych stosuje się 
struktury statyczne, których rozmiary i organizacja są 
niezależne od samych danych i liczby obiektów

Typowe dane statyczne:

dane proste

tablice statyczne danych prostych

rekord

tablica statyczna rekordów

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Dynamiczne struktury danych

Jeżeli problem jest złożony lub dane bardzo liczne, użycie 
statycznych struktur powoduje:

niemożność efektywnego zarządzania pamięcią

niemożność odzwierciedlenia związków pomiędzy 
poszczególnymi obiektami wśród przetwarzanych danych

Rozwiązaniem jest tworzenie dynamicznych struktur 
danych
, których organizacja w pewnym stopniu budowana 
jest już na etapie wykonania programu. Wymaga to:

dynamicznego zarządzania pamięcią

organizacji danych w struktury zawierające m.in. 
powiązania pomiędzy obiektami

Pozwala to na odzwierciedlenie związków pomiędzy 
obiektami, co umożliwia znacznie efektywniejsze 
przetwarzanie
danych (np. wyszukiwanie, sortowanie itp.)

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Tworzenie struktur 
dynamicznych

Elementarną strukturą danych w tym ujęciu jest rekord
który stanowi opis pojedynczego obiektu za pomocą 
pewnej liczby prostych danych (lub niewielkich struktur 
statycznych)

Element, który jest charakterystyczny dla struktur 
dynamicznych to wprowadzenie do każdego rekordu 
jednego lub kilku powiązań z innymi obiektami 
(podobnego lub innego typu)

W przypadku języka C++:

rekordy mają postać struktur (lub klas)

powiązania mają postać wskaźników

poszczególne obiekty tworzone są za pomocą 
dynamicznej alokacji pamięci

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Typowe struktury dynamiczne

Lista

jednokierunkowa

dwukierunkowa

cykliczna

Drzewo

drzewo binarne

Kolejka (zastosowanie listy)

FIFO

LIFO (Stos)

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Lista jednokierunkowa

Model:

Deklaracja w C++:

struct Rekord

{

  // zestaw danych ma temat jakiegoś obiektu,np.

  float dana;

  Rekord *next;  // wskaźnik na następny rekord

};

Rekord *begin=NULL; // wskaźnik na początek listy

    // NULL oznacza ostatni rekord

   // na początku lista jest pusta

...

Dane 1

begin

Dane 2

Dane n

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Przeglądanie listy

Służy do tego wskaźnik, który początkowo wskazuje na 

początek listy, a następnie cyklicznie przesuwa się na 

element następny aż do napotkania wartości 

NULL

;

void PokazListe()

{

if (begin==NULL)

   cout << "Lista pusta!\n";

 else

    {

     Rekord *r=begin;

  while (r!=NULL)

      {

 

     cout << r->dana<< endl;

     r=r->next;

   }

    }

}

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Pusta lista i dodawanie obiektów

Lista pusta:

begin

Dodanie elementu do listy:

begin

Dane 1

Dodanie drugiego elementu (na koniec 
listy):

Dane 1

begin

Dane 2

Dane 1

begin

Dane 2

Dodanie trzeciego elementu (na początek listy):

Dane 3

Dodanie czwartego elementu (w środek listy):

Dane 1

begin

Dane 2

Dane 3

Dane 4

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Dodanie obiektu do listy (C++)

Dodanie nowego obiektu na koniec listy:

Rekord *el=new Rekord;

// pominiemy tu kontrolę błędów alokacji

cin >> el->dana;

el->next=NULL;    

// nowy obiekt będzie ostatni

Rekord *wsk=begin;

if (wsk==NULL)  

// lista jest pusta

  

begin=el;

 else

{

  while (wsk->next!=NULL)  

// znalezienie końca

 

     wsk=wsk->next;

  wsk=el;
}

Dodanie nowego obiektu na początek listy:

Rekord *el=new Rekord;

cin >> el->dana;

el->next=begin;

   

// dawny pierwszy element

begin=el;

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Usuwanie obiektu z listy

Dane 1

begin

Dane 2

Dane 3

Dane 2

begin

Dane 1

Dane 3

Dane 2

begin

Dane 1

Dane 3

• Usunięcie obiektu w środku listy

• Usunięcie obiektu na początku listy

• Usunięcie obiektu na końcu listy

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Usuwanie obiektu (C++)

Usunięcie pierwszego obiektu listy:

if (wsk!=NULL)  

// lista nie jest pusta

{

  

Rekord *pierwszy=begin;

  

begin=begin->next;

  delete pierwszy;

}

Usunięcie ostatniego obiektu z listy:

if (wsk!=NULL)  

// lista nie jest pusta

{

  

Rekord *rek=begin;

  while ((rek->next)->next!=NULL)  

// przedost.

     

rek=rek->next;

  delete rek->next;

  rek->next=NULL;

}

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Przykład listy jednokierunkowej

Program 

LISTA.CPP

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Wskaźnik na koniec listy

Często występuje konieczność wykonania operacji na 
końcu listy (np. dopisanie nowego rekordu)

W takich wypadkach konieczne jest przeglądniecie całej 
listy po kolei aby dojść do końca

Przydatne może być zapamiętanie wskaźnika na ostatni 
rekord listy (wskaźnik ten będzie się zmieniał przy 
dodaniu elementu na koniec lub usunięciu ostatniego 
elementu)

Model:

...

Dane 1

begin

Dane n

end

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Lista cykliczna jednokierunkowa 

Model:

Ponieważ nie ma tu elementu ostatniego, podczas 
przeglądania listy należy pamiętać albo liczbę elementów albo 
sprawdzać czy adres elementu następnego jest równy 

begin

.

Wskaźnik 

begin

 może być przestawiony na dowolny z 

elementów listy (można przestawić jej początek)

Zastosowanie: zapamiętywanie danych zawierających cykl,
np. dane związane z kolejnymi miesiącami roku.

Struktura rekordu identyczna jak dla zwykłej listy 
jednokierunkowej

Dane 1

begin

Dane 2

Dane n

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Model:

Deklaracja w C++:

struct Rekord
{
  float dana;   

// przykładowe dane właściwe

 

  Rekord *prev;  

// wskaźnik na poprzedni rekord

  Rekord *next;  

// wskaźnik na następny rekord

};
Rekord *begin=NULL;
Rekord *end=NULL;  

// nie zawsze jest tworzony

Lista dwukierunkowa

...

begin

Dane 1

Dane 2

Dane n

end

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Model:

Ponieważ nie ma tu w zasadzie elementu pierwszego ani 
ostatniego, podczas przeglądania listy należy pamiętać albo 
liczbę elementów albo sprawdzać czy adres elementu 
następnego jest równy 

begin

.

Wskaźnik 

begin

 może być przestawiony na dowolny z elementów 

listy (można przestawić jej umowny początek)

Zastosowanie: zapamiętywanie danych zawierających cykl,
np. dane związane z kolejnymi miesiącami roku.

Struktura rekordu identyczna jak dlazwykłej listy dwukierunkowej

Lista cykliczna dwukierunkowa

...

begin

Dane 1

Dane 2

Dane n

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Cechy list

Łatwość wstawiania i usuwania elementów

Możliwość całkowitej zmiany kolejności elementów
(np. sortowanie)

Dostęp sekwencyjny do poszczególnych elementów
(konieczność przeszukiwania listy w celu dostępu do 
elementu o określonym numerze)

W przypadku listy jednokierunkowej przeszukiwanie 
odbywa się zawsze od elementu pierwszego w stronę 
ostatniego

Lista dwukierunkowa umożliwia przeszukiwanie 
elementów w obu kierunkach, a nawet wielokrotną 
zmianę kierunku przeglądania.

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Lista z atrapą (1)

W wielu rodzajach list tworzy się zawsze jeden rekord 
zwany atrapą

Jedynymi danymi, jakie są wypełnione w atrapie są 
powiązania (brak danych właściwych )

Celem tworzenia atrapy jest zapewnienie aby lista nigdy 
nie była pusta, a wskaźniki 

begin

 i 

end

 nigdy nie miały 

wartości NULL.

Ułatwia to opracowywanie algorytmów 
przetwarzających listę

usunięcie warunku czy lista jest pusta

ułatwienie dopisania pierwszego lub ostatniego 
elementu

W przypadku listy dwukierunkowej, atrapa może 
występować zarówno na początku, jak i na końcu listy

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Lista z atrapą (2)

Atrapa

begin

Dane n

• Lista jednokierunkowa z atrapą

...

Atrapa

Dane n

begin

end

• Lista dwukierunkowa z atrapą

...

Atrapa

begin

Dane n

• Lista cykliczna jednokierunkowa z atrapą

...

• Lista cykliczna dwukierunkowa z 
atrapą

Atrapa

Dane n

begin

...

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Kolejka FIFO (First In First Out)

Dopuszczalne operacje:

dopisanie elementu na początek listy

odczyt elementu z końca listy wraz z jego usunięciem

Realizacja może opierać się o listę jednokierunkową

Przykład realizacji: program 

FIFO.CPP

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Stos (kolejka LIFO - Last In First 
Out)

Dopuszczalne operacje:

dopisanie elementu na początek listy

odczyt pierwszego elementu z listy wraz z jego 
usunięciem

Realizacja może opierać się o listę jednokierunkową

Przykład realizacji: program 

LIFO.CPP

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Drzewa (1)

Drzewo to struktura dynamiczna o budowie 
hierarchicznej

Każdy element posiada jednego rodzica i może mieć 
kilka elementów potomnych

Model

Dane 1

Dane 11

Dane 12

Dane 13

Dane 121

Dane 122

Dane 123

Dane 131

Dane 132

Dane 1321

korzeń

liście

węzły

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Drzewa (2)

Drzewo daje możliwość odzwierciedlenia hierarchii 
obiektów występującej w rzeczywistości

przykład: zapis drzewa genealogicznego

Inną możliwością zastosowania drzewa jest 
optymalizacja przeszukiwania dużych zbiorów obiektów. 
Celem jest umożliwienie dojścia do szukanego obiektu 
jak najkrótszą drogą

Warunkiem jest odpowiednie uporządkowanie obiektów 
już na etapie ich dodawania do drzewa

Algorytm przeglądania drzewa nie jest jednoznaczny, 
np.

przeglądanie poziomami od korzenia do liści

przeglądanie od gałęzi lewej do prawej

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Drzewa binarne

Drzewo binarne to drzewo, w którym każdy węzeł 
posiada dokładnie dwa powiązania z węzłami 
potomnymi

Model:

Dane 1

Dane 11

Dane 12

Dane 121

Dane 122

Dane 111

Dane 112

Dane 1121

Dane 1122

Dane 1211

background image

Podstawy programowania II - Dynamiczne struktury 

danych

Drzewa binarne (C++)

Deklaracja:

struct Rekord
{
  float dana;   

// przykładowe dane właściwe

 

  Rekord *child1, *child2;  

// obiekty potomne

};
Rekord *root=NULL;  

// korzeń

  

background image

 

 

NULL


Document Outline