background image

Algorytmy i struktury danych

Wykład 3



Podstawy struktur danych



Liniowe struktury danych (listy)



Rodzaje struktur liniowych



Implementacja list



Podstawowe operacje na listach jednokierunkowych

background image

2

Algorytmy i struktury danych

Definicja struktury danych

Definicja

Struktur

ą

 danych nazywamy trójk

ę

 uporz

ą

dkowan

ą

   

S = (D, R, e)

,

gdzie:

D

– oznacza zbiór danych elementarnych   

R={r

we

, N}

– jest zbiorem dwóch relacji okre

ś

lonych na strukturze danych:

– relacja wej

ś

cia do struktury danych S,

– relacja  nast

ę

pstwa (porz

ą

dkuj

ą

ca) struktur

ę

 S,

e

– jest elementem wej

ś

ciowym do struktury danych S 

(nie jest to element danych struktury danych S).

D

e

r

we

×

D

D

N

×

background image

3

Algorytmy i struktury danych

Zbiór danych elementarnych 

D



Zbiór danych elementarnych jest sko

ń

czony i dla wygody operowania 

oznaczeniami jego elementów poszczególne dane s

ą

 indeksowane od 

warto

ś

ci 1 w kierunku warto

ś

ci wi

ę

kszych.



Przykład: 



Liczno

ść

 powy

Ŝ

szego zbioru danych elementarnych wynosi 5, czyli 

{

}

5

4

3

2

1

d

,

d

,

d

,

d

,

d

 

=

D

5

D

=

background image

4

Algorytmy i struktury danych

Dane elementarne - zmienne programowe



Dane elementarna

d

i

s

ą

 poj

ę

ciem abstrakcyjnym, rozumianym jako tzw. 

„nazwana warto

ść

”. Jest ona okre

ś

lana jako uporz

ą

dkowana dwójka 

elementów:

, gdzie:



n

i

– nazwa danej,



w

i

– aktualna warto

ść

 danej z okre

ś

lonej dziedziny warto

ś

ci.



Zmienna programowa jest poj

ę

ciem zwi

ą

zanym z realizacj

ą

 danej 

w konkretnym 

ś

rodowisku programistycznym. Posiada zdefiniowan

ą

 

nazw

ę

, wraz z okre

ś

leniem dziedziny warto

ś

ci, któr

ą

 mo

Ŝ

e przyjmowa

ć

i

i

i

w

n

d

,

=

background image

5

Algorytmy i struktury danych

Relacja 

r

we

– wskazanie korzenia struktury S



Relacja                       , jest opisywana poprzez zbiór (jedno- lub 
wieloelementowy) par uporz

ą

dkowanych elementów, z których pierwszym 

jest zawsze element wej

ś

ciowy 

e

, natomiast drugim elementem jest jedna 

z danych elementarnych ze zbioru 

D



Element 

d

i

„uczestnicz

ą

cy” w relacji

r

WE

nazywamy korzeniem struktury 

danych S



Struktura musi mie

ć

 zdefiniowany co najmniej jeden korze

ń

.



Przykład:

Je

ś

li struktura S posiada dwa korzenie: d

2

oraz d

5

, to

{

}

 

d

,

e

,

d

,

e

 

r

5

2

we

=

D

e

r

we

×

background image

6

Algorytmy i struktury danych

Relacja 

N

– ustalenie porządku struktury S



Relacja nast

ę

pstwa opisuje wzajemne uporz

ą

dkowanie elementów 

w strukturze danych S. Porz

ą

dek struktury opisujemy w postaci zestawów 

par uporz

ą

dkowanych elementów.



Przykładowy porz

ą

dek pi

ę

cioelementowej struktury danych S:

{

}

3

5

4

3

4

1

3

1

1

2

d

,

d

,

d

,

d

,

d

,

d

,

d

,

d

,

d

,

d

 

N

=

poprzednik

następnik

background image

7

Algorytmy i struktury danych

Model grafowy struktury danych



Aby łatwiej zobrazowa

ć

 struktur

ę

 danych i w ten sposób lepiej j

ą

zrozumie

ć

mo

Ŝ

na zbudowa

ć

 dla niej model grafowy. W modelu tym:



w

ę

zły (wierzchołki) oznaczaj

ą

 poszczególne dane elementarne,



łuki (strzałki) słu

Ŝą

 do odwzorowania nast

ę

pstw poszczególnych danych 

elementarnych w strukturze S.

Przykład: Model grafowy dla opisywanej struktury S:

{

}

5

4

3

2

1

,

,

,

,

d

d

d

d

d

D

=

{

}

5

2

,

,

,

d

e

d

e

r

we

=

{

}

3

5

4

3

4

1

3

1

1

2

,

,

,

,

,

,

,

,

,

d

d

d

d

d

d

d

d

d

d

N

=

e

d

2

d

5

d

1

d

3

d

4

liść

korzeń

korzeń

background image

8

Algorytmy i struktury danych

Liniowe struktury danych

Wyró

Ŝ

niamy cztery rodzaje list:



jednokierunkowe listy niecykliczne,



dwukierunkowe listy niecykliczne,



jednokierunkowe listy cykliczne (pier

ś

cienie jednokierunkowe),



dwukierunkowe listy cykliczne (pier

ś

cienie dwukierunkowe).

background image

9

Algorytmy i struktury danych

Jednokierunkowe listy niecykliczne

Model grafowy listy jednokierunkowej:

e

d

1

d

2

d

3

d

n

background image

10

Algorytmy i struktury danych

Dwukierunkowe listy niecykliczne

Model grafowy listy dwukierunkowej:

e

d

1

d

2

d

3

d

n

background image

11

Algorytmy i struktury danych

Pierścień jednokierunkowy

Model grafowy pier

ś

cienia jednokierunkowego:

e

d

1

d

2

d

3

d

n

background image

12

Algorytmy i struktury danych

Pierścienie dwukierunkowe

Model grafowy pier

ś

cienia dwukierunkowego:

e

d

1

d

2

d

3

d

n

background image

13

Algorytmy i struktury danych

Podstawowe operacje na listach

1.

Wyszukiwanie elementu na li

ś

cie

2.

Doł

ą

czanie elementu do listy

3.

Usuwanie elementu z listy

4.

Przestawianie elementów na li

ś

cie

5.

Porz

ą

dkowanie (sortowanie) listy

background image

14

Algorytmy i struktury danych

Dynamiczne realizacje struktur listowych 



Element listy zawiera:



Dane elementarne,



Odwzorowanie relacji nast

ę

pstwa – informacja o dowi

ą

zaniu 

do innych elementów;

dane

wska

ź

nik na nast

ę

pny element

startPtr

NULL

Ogon (tail)

Głowa (head)

background image

15

Algorytmy i struktury danych

dane 

elementarne

dowiązanie 

do kolejnego 

elementu 

Dynamiczne realizacje struktur listowych 



Deklaracja elementu listy:

struct Node {

char dane;
struct Node *next;

};

typedef struct Node *NodePtr;

/* definicja typu wska

ź

nikowego do struktury Node */

background image

16

Algorytmy i struktury danych

Wyszukiwanie elementu na liście

Algorytm wyszukania elementu na li

ś

cie jednokierunkowej:



Cel:



Wyszukanie elementu na li

ś

cie; 



Dane wej

ś

ciowe:



Wska

ź

nik na pierwszy element listy;



Kryterium poszukiwania, np. warto

ść

 danej elementarnej;



Uwagi:



W skrajnym przypadku nale

Ŝ

y przejrze

ć

 wszystkie elementy 

(zło

Ŝ

ono

ść

Θ

(n));

background image

17

Algorytmy i struktury danych

Algorytm wyszukiwania elementu na liście jednokierunkowej

1. Rozpocznij wyszukiwanie od pierwszego elementu listy;

2. Dopóki nie osi

ą

gni

ę

to ko

ń

ca listy oraz szukana warto

ść

 jest 

Ŝ

na od warto

ś

ci aktualnego elementu przejd

ź

 do nast

ę

pnego 

elementu listy;

3. Zwró

ć

 wska

ź

nik na znaleziony (aktualny) element lub warto

ść

 

NULL (gdy szukanej warto

ś

ci nie znaleziono)

startPtr

D

A

C

B

background image

18

Algorytmy i struktury danych

Algorytm wyszukiwania elementu na liście jednokierunkowej

struct Node {

char dane;
struct Node *next;

};

typedef struct Node *NodePtr;

Node *Find (Node *startPtr, char szukwart) {

NodePtr currPtr = startPtr;      

/* adres na pierwszy element listy */

while ((currPtr != NULL) && (currPtr -> dane != szukwart))

currPtr = currPtr -> next;

return currPtr;

background image

19

Algorytmy i struktury danych

Dynamiczne realizacje struktur listowych 

Przykład:

Node *element = Find (startPtr, ‘C’);

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NULL

startPtr

D

A

B

C

currPtr

Warto

ść

 szukana: C

currPtr: startPtr

currPtr -> dane: A

background image

20

Algorytmy i struktury danych

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NULL

startPtr

D

A

B

C

Dynamiczne realizacje struktur listowych 

Przykład (cd):

Node *element = Find (startPtr, ‘C’);

currPtr

Nazwa szukana: C

currPtr: currPtr -> next

currPtr -> dane: B

background image

21

Algorytmy i struktury danych

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

NULL

C

NULL

startPtr

D

A

B

C

Dynamiczne realizacje struktur listowych 

Przykład (cd.)

Node *element = Find (startPtr, ‘C’);

currPtr

Nazwa szukana: C

currPtr: currPtr -> next

currPtr -> dane: C

background image

22

Algorytmy i struktury danych

Algorytm dołączania elementu do uporządkowanej listy 

jednokierunkowej



Cel:



Dodanie nowego elementu (z warto

ś

ci

ą

 C) do listy uporz

ą

dkowanej 

(we wła

ś

ciwe miejsce); 



Dane wej

ś

ciowe:



Wska

ź

nik na pierwszy element listy;



Dane do wstawienia na list

ę

;

startPtr

A

B

D

C

background image

23

Algorytmy i struktury danych

Algorytm dołączania elementu do uporządkowanej listy jednokierunkowej

1. Utwórz element i ustal dane elementarne

2. Znajd

ź

 miejsce wstawienia elementu na list

ę



Zainicjuj currPtr na pocz

ą

tek listy a prevPtr na NULL;



Dopóki currPtr jest ró

Ŝ

ny od NULL i warto

ść

 wstawiana jest wi

ę

ksza 

od currPtr->dane:

• Ustaw prevPtr na currPtr;

• Przesu

ń

currPtr na nast

ę

pny element listy;

3. Wstaw element na list

ę

:



wstaw element jako pierwszy na li

ś

cie:

• Ustaw pole next elementu wstawianego na pierwszy element 

listy;

• Ustaw wska

ź

nik do listy na element wstawiony;



lub  wstaw element w wyznaczone miejsce na li

ś

cie:

• Ustaw pole next elementu prevPtr na element wstawiany;

• Ustaw pole next elementu wstawianego na element currPtr;

background image

24

Algorytmy i struktury danych

1. Utwórz element i ustal dane elementarne

struct Node {

char dane;
struct Node *next; };

typedef struct Node *NodePtr;

int insert (NodePtr *startPtr, char wstwart) {

struct Node *newPtr, *currPtr, *prevPtr;
int retcode;

/* Utwórz element Node */

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

startPtr

currPtr

prevPtr

newPtr

A

B

D

background image

25

Algorytmy i struktury danych

1. Utwórz element i ustal dane elementarne (cd.)

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

ę

ci*/

return 1;

else 
/* Ustal dane elementarne w Node */

newPtr -> dane = wstwart;

newPtr -> next = NULL;
/* Zainicjowanie wska

ź

ników pomocniczych */

currPtr = startPtr; /* ustaw wska

ź

nik na głow

ę

 listy */ 

prevPtr = NULL;

startPtr

currPtr

prevPtr

newPtr

A

B

D

NULL

C

background image

26

Algorytmy i struktury danych

2. Znajdź miejsce wstawienia elementu na listę

/* Znajd

ź

 miejsce wstawienia */

while ((currPtr != NULL) && (wstwart  > currPtr->dane))
{

prevPtr = currPtr;
currPtr = currPtr -> next;

}

startPtr

currPtr

prevPtr

newPtr

A

B

D

C

background image

27

Algorytmy i struktury danych

3. Wstaw element na listę

if (prevPtr == NULL)

/* Wstaw element jako pierwszy na li

ś

cie */

{

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

}

startPtr

currPtr

prevPtr

newPtr

D

F

G

NULL

NULL

C

NULL

startPtr

newPtr

prevPtr

G

currPtr

C

D

F

NULL

background image

28

Algorytmy i struktury danych

3. Wstaw element na listę (cd.)

/* Wstaw element w miejsce mi

ę

dzy prevPtr a currPtr */

else 

{

newPtr->next = currPtr;
prevPtr->next = newPtr;

}

}

return 0;

}

startPtr

A

B

D

C

background image

29

Algorytmy i struktury danych

Algorytm dołączania elementu do listy jednokierunkowej – pełny kod

int insert (NodePtr *startPtr, char wstwart) {

struct Node *newPtr, *currPtr, *prevPtr;

int retcode=1;
/* Utwórz element Node */
newPtr = (struct Node *)malloc(sizeof(Node));
if (newPtr == NULL)  /* weryfikacja przydzielonej pami

ę

ci*/

return 1;

else 

{ /* Ustal dane elementarne w Node */

newPtr -> dane = wstwart;
newPtr -> next = NULL;

/* Zainicjowanie wska

ź

ników pomocniczych */

currPtr = startPtr;   /* ustaw wska

ź

nik na głow

ę

 listy */ 

prevPtr = NULL;
while ((currPtr != NULL) && (wstwart > currPtr->dane)) {

prevPtr = currPtr;

currPtr = currPtr -> next;

}

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

ś

cie */

newPtr -> next = *startPtr;

*startPtr = newPtr;

}

else   { /* Wstaw element w miejsce mi

ę

dzy prevPtr a currPtr */

newPtr->next = currPtr;

prevPtr->next = newPtr;

}

}

return 0;

}

background image

30

Algorytmy i struktury danych

Algorytm usuwania elementu z uporządkowanej listy jednokierunkowej



Cel:



Usuni

ę

cie elementu z listy; 



Dane wej

ś

ciowe:



Wska

ź

nik na pierwszy element listy startPtr;



Opis usuwanego elementu, np. warto

ść

 danej elementarnej;

background image

31

Algorytmy i struktury danych

Idea algorytmu usuwania elementu z uporządkowanej listy jednokierunkowej

A

startPtr

B

C

Przed 
usuni

ę

ciem 

elementu B:

A

startPtr

B

C

Po usuni

ę

ciu:

background image

32

Algorytmy i struktury danych

Algorytm usuwania elementu z uporządkowanej listy jednokierunkowej

1. Znajd

ź

 element do usuni

ę

cia na li

ś

cie;

2. Je

Ŝ

eli nie znaleziono elementu, zwró

ć

 kod bł

ę

du;

3. Usu

ń

 znaleziony element z listy.

background image

33

Algorytmy i struktury danych

Algorytm usuwania elementu z uporządkowanej listy jednokierunkowej



Je

Ŝ

eli dane s

ą

 zgodne z danymi pierwszego elementu listy

usu

ń

 pierwszy element listy;

int delete (NodePtr *startPtr, char uswart)

{

Node *prevPtr, *currPtr, *tempPtr;

if (*startPtr == NULL)   

/* Lista pusta */

return 1;

else   
{

if (uswart == (*startPtr)->dane)    /* Usu

ń

 pierwszy element listy 

*/   

{    

tempPtr = *startPtr;
*startPtr = (*startPtr)->next;
free (tempPtr);

}

background image

34

Algorytmy i struktury danych

Algorytm usuwania elementu z uporządkowanej listy jednokierunkowej

...



Znajd

ź

 element do usuni

ę

cia na li

ś

cie

:

else

{ /* znajd

ź

 na li

ś

cie element do usuni

ę

cia */ 

prevPtr = *startPtr;    

/* pocz

ą

tek listy */

currPtr = (*startPtr)->next; 

/* drugi element*/

while (currPtr != NULL && currPtr -> dane != uswart)

{

prevPtr = currPtr;
currPtr = currPtr -> next;

}

background image

35

Algorytmy i struktury danych

Algorytm usuwania elementu z uporządkowanej listy jednokierunkowej

...



Znajd

ź

 element do usuni

ę

cia na li

ś

cie (cd.):



Je

Ŝ

eli nie znaleziono elementu, zwró

ć

 kod bł

ę

du



Usu

ń

 znaleziony element;

if (currPtr == NULL)

return 1;     /* element nie został znaleziony */

else

{  /* Usu

ń

 znaleziony element */

tempPtr = currPtr;
prevPtr->next = currPtr->next;
free (tempPtr);
}  }  }

return 0;

}

background image

36

Algorytmy i struktury danych

Algorytm usuwania elementu z uporządkowanej listy jednokierunkowej

int delete (NodePtr *startPtr, char uswart)

{ Node *prevPtr, *currPtr, *tempPtr;

if (*startPtr == NULL)    /* Lista pusta */

return 1;

else  {

if (uswart == (*startPtr)->dane)  {  /* Usu

ń

 pierwszy element listy */   

tempPtr = *startPtr;

*startPtr = (*startPtr)->next;

free (tempPtr);

}

else {/* znajd

ź

 w li

ś

cie element do usuni

ę

cia */ 

prevPtr = *startPtr;       

/* pocz

ą

tek listy */

currPtr = (*startPtr)->next; 

/* drugi element*/

while (currPtr != NULL && currPtr -> dane != uswart)  {

prevPtr = currPtr;

currPtr = currPtr -> next;

}
if (currPtr == NULL)

return 1;     /* element nie został znaleziony */

else  {  /* Usu

ń

 znaleziony element */

tempPtr = currPtr;

prevPtr->next = currPtr->next;

free (tempPtr);

}  

}  

}

return 0;

}

background image

37

Algorytmy i struktury danych

Dołączanie elementu do uporządkowanej listy dwukierunkowej

Uwagi:



ka

Ŝ

dy element posiada dodatkowe pole (wska

ź

nik) prev, który 

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;

Czy potrafisz dostosowa

ć

 zaprezentowane algorytmy dla 

list dwukierunkowych?

background image

38

Algorytmy i struktury danych

Dołączanie elementu do uporządkowanej listy 

jednokierunkowej cyklicznej

Uwagi:



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, 

mo

Ŝ

na zastosowa

ć

 wartownika – dowi

ą

zanie do pierwszego 

elementu (umownego);

Czy potrafisz dostosowa

ć

 zaprezentowane algorytmy 

dla list cyklicznych?

background image

39

Algorytmy i struktury danych