nw asd w5

background image

1















































Dynamiczne struktury danych

Lista, Stos, Kolejka

Podstawowa terminologia

 Typy danych (

Data types

)

 Struktury Danych (

Data Structures

)

 Abstrakcyjne typy danych ADT (

Abstract Data Types

)

ASD

LJ

S

background image

2















































Typy danych

Typ danych - zbiór wartości, które może przyjmować zmienna (danego typu) lub
wyrażenie, albo które mogą być generowane przez operator lub funkcję.

Moc typu danych to liczba różnych wartości należących do typu. Moc typu wyznacza
wielkość pamięci (w bitach) potrzebnej do reprezentowania wartości tego typu.

Z typem danych skojarzone są operatory działające na wartościach tego typu.
Operatory mogą być standardowe (zdefiniowane w języku programowania) lub
niestandardowe (zdefiniowane przez użytkownika, programistę) w postaci
konkretnych funkcji.

Operatory stanowią integralny element definicji typu danych.

ASD

LJ

S

Rodzaje typów danych:



proste



złożone

Proste typy danych

Proste typy danych - typy, których elementy (wartości) nie składają się z elementów
innych typów danych (są nierozkładalne).

Przykłady prostych typów danych:



bitowy (

bit

)



bajtowy (

byte

)



całkowity (

integer

)



rzeczywisty (

real

)



logiczny (

boolean

)



znakowy (

char

)



łańcuchowy (

string

)



wyliczeniowy (

enumerated

)



okrojony (

subrange

)



wskaźnikowy (

pointer

)

ASD

LJ

S

background image

3















































Złożone typy danych

Złożony typ danych stanowi zazwyczaj kombinacje typów prostych oraz

mechanizmów agregujących.

Przykłady złożonych typów danych:



tablica (

array

)



rekord (

record

)



zbiór (

set

)



lista (

list

)



drzewo (

tree

)



graf (

graph

)



kolejka (

queue

)



stos (

stack

)

ASD

LJ

S

Mechanizmy agregujące za pomocą których tworzy się typy złożone z typów
prostych są zależne od języków programowania.

Typy danych

Podstawowa zasada realizowana przez większość języków programowania w
odniesieniu do typów danych określa dostęp do jedno lub wielobajtowych komórek
pamięci (

cells

).

Komórkę można traktować jako miejsce przechowujące pojedynczą wartość,
należącą do danego typu podstawowego lub złożonego.
Liczby całkowite i zmiennoprzecinkowe są traktowane jako typy arytmetyczne
(

arithmetic types

).

Aspekty rozpatrywania typów danych:

1. Statyczny – system typu (

type system

) związany ze zbiorem wartości

odniesionym do konkretnego typu,

2. Dynamiczny - związany z operacjami na wartościach z definiowanego zbioru.

ASD

LJ

S

background image

4















































Struktury danych

Struktura danych - zbiór zmiennych określonych typów, posiadający określoną
organizację (strukturę) i związany z nią sposób dostępu do danych.

Struktury danych opisują sposób organizacji oraz metody dostępu do danych.

Podstawowe mechanizmy agregujące: tablica, rekord, plik, drzewo, lista,
struktury, unie.

E – nazwa struktury
R

we

– relacja wejściowa

R

wew

– relacja węwnętrzna

Wirth N:
Algorytmy+struktury danych=programy.

Podstawowymi jednostkami tworzącymi struktury danych są komórki (

cells

).

Struktury danych tworzy się poprzez agregacje takich komórek.

R

we

E

R

wew

ASD

LJ

S

Struktury danych

ASD

LJ

S

Definiując strukturę danych, wiążemy ją z operacjami służącymi do:



wstawiania nowych danych,



wydobywania konkretnych danych na podstawie ustalonych kryteriów
wyszukiwania,



przeglądania wszystkich danych w strukturze w zadanej kolejności,



porządkowania danych według zadanego kryterium,



usuwania danych ze struktury.

background image

5















































Abstrakcyjne typy danych

 ADT (

Abstract Data Types

) – zbiór danych tworzony i opisywany w formalny

sposób poprzez własności danych i operacji wykonywanych na nich (a nie
poprzez reprezentację danych w pamięci i ich implementację).

 ADT - zbiór danych i operacji na tych danych, które są dostępne jedynie za

pośrednictwem zdefiniowanego interfejsu.

 Interfejs ADT określa sposób dostepu do danych i definiuje operacje na nich.

 Implementacja ADT polega na zdefiniowaniu jego odpowiednika w kategoriach

konkretnego języka programowania oraz zapisaniu w tym języku funkcji i
procedur do wykonywania podstawowych operacji.

Podstawowe ADT: lista, stos, kolejka.

ADT jest połączeniem modelu danych i zbioru operacji jakie można na tym modelu
wykonać. Dwa identyczne modele, połączone z różnymi zbiorami operacji
określają różne ADT.

ASD

LJ

S

Lista

Lista (

List

) - skończona sekwencją elementów (obiektów) ułożonych w liniowym

porządku.

W matematycznym sensie lista to zbiór elementów :

L = (a

1

, a

2

, ..., a

n

)



Lewy koniec listy a

1

- głowa listy (

head

),



Prawy koniec listy a

n

- ogon listy (

tail

),



Długością listy:L=n

Lista pusta L=( ) - szczególny przypadek listy.

ASD

LJ

S

background image

6















































Lista

Lista - przykłady:

 L = (I, II, III, ..., XII) – lista miesięcy,

 L = (hel, neon, argon, krypton, ksenon, radon) – lista gazów

szlachetnych uporządkowanych zgodnie z masą atomową,

 L = <(0, 0), (1, 0), (1, 1)> – lista list współrzędnych wierzchołków

figury geometrycznej:

(1 0)

(1 1)

(0 0)

ASD

LJ

S

Lista

L1 = (a

1

, a

2

, ..., a

n

)

L2 = (b

1

, b

2

, ..., b

m

),

0 ≤ i ≤ j ≤ n, m

Pozycja elementu na liście, wystąpienie (

occurence

) elementu:

L[i] = a

i

Podlista:

L[i..j] = (a

i

, a

i+1

, ..., a

j

)

Złożenie list, konkatenacja (

concatenate

):

L1 & L2 = (a

1

, a

2

, ..., a

n

, b

1

, b

2

, ..., b

m

)

Podstawowe własności:

ASD

LJ

S

background image

7















































Lista



Operacje na początku (końcu ) listy:

-

wstawianie,

-

usuwanie,

-

dostęp do elementu.



Operacje złożone:

-

wyszukiwanie elementu,

-

wstawianie za k-ty element,

-

usunięcie k-tego elementu,

-

przestawienie k-tego elementu na początek (koniec),

-

odwracanie listy,

-

łączenie list.

ASD

LJ

S

Aby zbudować ADT reprezentujący listę na podstawie jej pojęcia matematycznego
należy zdefiniować zestaw operacji wykonywanych na elementach listy.

Listy powiązane

Linked lists

background image

8

















































Lista

Rodzaje list:



Jednokierunkowa (powiązana pojedynczo),



Dwukierunkowa (powiązana podwójnie),



Cykliczna.

Rodzaje implementacji:



Wskaźnikowa (dowiązaniowa),



Tablicowa.

ASD

LJ

S

Lista jednokierunkowa

Lista jednokierunkowa (

Singly linked list

).

Przykładowa definicja listy:

struct node
{

int key;
node *next;

};

node *head, *tail;

głowa
(head)

ogon

(tail)

null

wartownik

(sentinel)

węzeł

(node, cell)

ASD

LJ

S

background image

9















































Lista jednokierunkowa

Każdy element listy przechowuje dwa typy informacji:

1.

Merytoryczną (widoczną na zewnątrz), zw. kluczem (

key

),

2.

Organizacyjną (widoczna wewnątrz), którą jest wskaźnik (

pointer

) do

innego elementu danej listy,

ASD

LJ

S

/ (NULL)

. . .

/

głowa listy

ogon listy

. . .

element listy

Inf. organiz. (wskaźnik)

Inf. merytorycz. (klucz)

L.head

Lista jednokierunkowa

Reprezentacja dowiązaniowa listy jednokierunkowej.

x.key - wartość pola klucza elementu listy,

x.next – wskaźnik do następnika (jeżeli x.next ma wartość

NULL

, to x jest

ogonem)

L.head – wskazuje na pierwszy element listy (głowę) (jeżeli L.head ma wartość

NULL

to lista jest pusta).

key

next

/

L.head

tail

. . .

head

ASD

LJ

S

background image

10















































Lista jednokierunkowa

Podstawowe operacje listy jednokierunkowej (implementacja dowiązaniowa).

Wyszukiwanie elementu x o kluczu k na liście L..
(Pseudokod).

SEARCH_1LIST(L,k)
{

x=L.head;
WHILE(x≠NULL and x.key≠k){

x=x.next;

}
return(x)

}

Złożonośc algorytmu O(n).

ASD

LJ

S

Lista jednokierunkowa

Podstawowe operacje listy jednokierunkowej (implementacja dowiązaniowa).

Wstawianie elementu x (pole key zostało
zainicjowane) na początek listy L.
(Pseudokod).

INSERT_1LIST(L,x)
{

x.next=L.head;
L.head=x;

}

Wstawianie elementu o kluczu k na początek listy:

node *head;
void insert(int k)
{

node *ptr=new node;
ptr->key=k;
ptr->next=head;
head=ptr;

}

Złożonośc algorytmów O(1).

Usuwanie elementu x z początku listy L.

(Pseudokod).

DELETE_1LIST(L,x)
{

L.head=x.next;

}

ASD

LJ

S

background image

11















































Lista jednokierunkowa

Wyszukiwanie elementu o kluczu k z użyciem wartownika.

node *head, *sentinel;

node *search (int k)
{

sentinel->key=k;
node *ptr=head;
while (ptr->key!=k)

ptr=ptr->next;

if(ptr==sentinel)

return NULL;

else

return ptr;

}

ASD

LJ

S

Podstawowe operacje listy jednokierunkowej (implementacja dowiązaniowa).

Tablicowa reprezentacja listy

Lista w reprezenyacji tablicowej ma postać rekordu,
który składa się z:



Tablicy o rozmiarze wystarczającym do
zapamiętania najdłuższej przewidywanej listy.



Zmiennej last przechowującej pozycję ostatniego
elementu.

A[1]
A[2]

A[i]

.
.

A[n]

.
.
.
.

maxLenght

last

Właściwa lista

Niewykorzystana
pamięć

Tablica A reprezentująca listę L = (a

1

,a

2

,..a

i

...,a

n

),

A[i]=a

i

, i=1H.,n.

typedef struct {

int A[maxLenght];
int last;

} LIST;

LIST *L

ASD

LJ

S

background image

12















































Tablicowa reprezentacja listy

Operacje reprezentacji tablicowej.

Wstawianie elementu o wartości x na pozycję p w liście L.
(Pseudokod).

INSERT_TAB(L,x,p)
{

IF(L.last > maxLenght)

return(„lista pełna”);

ELSE{
FOR q=L.last,L.last-1,...p

L.A[q+1]=L.A[q];

L.A[p]=x;
L.last=L.last+1;
}

}

Złożonośc algorytmu O(n).

ASD

LJ

S

Tablicowa reprezentacja listy

Operacje reprezentacji tablicowej.

Usuwanie elementu z pozycji p z listy L. (Pseudokod).

DELETE_TAB(L,p)
{

IF(p>L.last or p<1)

return(„w liście brak żądanej pozycji”);

ELSE{

L.last=L.last–1;
FOR q=p,p+1,...L.last

L.A[q]=L.A[q+1];

}

}

Złożoność algorytmu O(n).

ASD

LJ

S

background image

13















































Lista dwukierunkowa

Double linked list

Tablicowa reprezentacja listy

Operacje reprezentacji tablicowej.

Wyszukiwanie elementu x w liście L i zwracanie pozycji.
(Pseudokod).

SEARCH_TAB(L,x)
{

FOR q=1,2,...L.last

IF(L.A[q]==x)

return(q);

return(L.last+1);// jeśli nie znaleziono

}

Złożonośc algorytmu O(n).

ASD

LJ

S

background image

14















































Lista dwukierunkowa

/

key

next

/

L.head

tail

. . .

prev

Schemat listy dwukierunkowej.

struct node
{

int key;
node *prev, *next;

};

node *head, *tail;

ASD

LJ

S

Lista dwukierunkowa

Podstawowe operacje listy dwukierunkowej (reprezentacja dowiązaniowa).

Wstawianie elementu x (którego pole key zostało zainicjowane) na
początek listy L. (Pseudokod).

INSERT_2LIST(L,x)
{

x.next=L.head;
IF(L.head ≠ NULL)

L.head.prev=x;

L.head=x;
x.prev=NULL;

}

Złożonośc algorytmu O(1).

ASD

LJ

S

background image

15















































Lista dwukierunkowa

Wyszukiwanie elementu x o kluczu k na liście L.
(Pseudokod).

SEARCH_2LIST(L,k)
{

x=L.head;
WHILE (x≠NULL and x.key≠k){

x=x.next;

}
retun(x)

}

Złożonośc algorytmu O(n).

ASD

LJ

S

Podstawowe operacje listy dwukierunkowej (reprezentacja dowiązaniowa).

Lista dwukierunkowa

Usuwanie elementu x z listy L. (Pseudokod).

DELETE_2LIST(L,x)
{

IF(x.prev ≠ NIL)

x.prev.next=x.next;

ELSE

L.head=x.next;

IF(x.next ≠ NULL)

x.next.prev=x.prev;

}

Złożonośc algorytmu DELETE_2LIST: złożoność O(1). Pesymistyczna złożoność usunięcia
elementu o zadanym kluczu wynosi O(n) , ponieważ do wyznaczenia wskaźnika x należy
wywołać SEARCH_2LIST.

ASD

LJ

S

Podstawowe operacje listy dwukierunkowej (reprezentacja dowiązaniowa).

background image

16















































Lista dwukierunkowa

Wielotablicowa reprezentacja listy dwukierunkowej.

Każdy węzeł listy dwukierunkowej jest rekordem o trzech polach next, key, prev.

Dla danego indeksu k wartości Key[k], Next[k] oraz Prev[k] określają element
(węzeł) listy.

/

11

21

25

41

/

L.head

Lista L reprezentowana za pomocą tablic: Next, Key, Prev.

1

2

3

4

5

6

7

8

3

5

7

Prev

/

41

25

21

Key

11

/

2

3

Next

5

7

L

ASD

LJ

S

Lista dwukierunkowa

Reprezentacja listy dwukierunkowej w pojedynczej tablicy.

/

11

21

25

41

/

L.head

Lista L reprezentowana za pomocą pojedynczej tablicy A.

7

25

4

1

41

/

13

21

1

/

11

7

1

2

3

4

5

6

7

8

9

10

11

12 13

14

15 15

17 18

13

A

L

ASD

LJ

S

background image

17















































Przykładowe struktury listowe

a)

b)

c)

d)

ASD

LJ

S

Lista z przeskokami

ASD

LJ

S

Lista z przeskokami (

skip list

) jest przeznaczona do przechowywania danych

uporządkowanych.

 Oparta na równoległej, warstwowej posortowanej liście jednokierunkowej.

 Każdy element oprócz dowiązania do następnika może posiadać pewną liczbę

dowiązań do elementów dalszych.

 Liczba połączeń elementu z innymi określa jego stopień (

degree

,

height

), przy czym

i-te łącze wskazuje na kolejny element stopnia co najmniej i.

 Skip list stanowi alternatywę dla zrównoważonych drzew binarnych.

 Oczekiwana złożoność operacji wyszukiwania, wstawiania nowego elementu do

listy oraz usunięcia elementu wynosi O(logn).

 Pierwszy element ma zawsze maksymalny stopień a dodawane elementy

otrzymują stopień wylosowany wg geometrycznego rozkładu prawdopodobieństwa

p

i

(1 − p), gdzie: p≤1/2

background image

18















































Lista z przeskokami

ASD

LJ

S

42

HD

6

10

20

25

38

/

33

E

HD

/

C

C

D

E

A

B

A

A

Czteropoziomowa skip list

Wyszukiwanie w trójpoziomowej skip list

Porównanie implementacji list

 Implementacja tablicowa wymaga a priori znajomości maksymalnej długości

listy.

 Niektóre operacje w tablicowej implementacji trwają dłużej np.

INSERT

,

DELATE

.

 Implementacja tablicowa z powodu statycznego operowania pamięcią jest

nieefektywna.

 Implementacja wskaźnikowa wymaga uwagi w działaniu na wskaźnikach.

ASD

LJ

S

background image

19















































Zastosowania list

Zastosowania list powiązanych.



Listy w aplikacjach obsługujących pocztę elektroniczną,



Listy przewijane,



Zarządzanie pamięcią przez system operacyjny w zakresie sterowania

procesami,



Inne struktury danych oparte na listach: stosy, kolejki, grafy, tablice

asocjacyjne.

ASD

LJ

S

Stos

Stack

background image

20















































Stos

Podstawowa terminologia.

Stos – struktura liniowo uporządkowanych danych określonego typu. Wszystkie

dostępne operacje wykonywane są na jednym końcu tej struktury, szczycie
stosu (

top

).

Stos obsługiwany jest według zasady LIFO (

Last-in-First-out

).

Podstawowe operacje:



Wstawianie elementu x do struktury danych (

PUSH

),



Usuwanie elementu ze struktury danych (

POP

),



Sprawdzenie czy stos jest pusty (

EMPTY

),



Sprawdzenie czy stos jest pełny (

FULL

),



Zwrot elementu szczytu stosu, bez usuwania go ze struktury danych
TOP (S).

ASD

LJ

S

Stos

1.

Zakładając, że skrajnie prawy element sekwencji (a

1

, a

2

, ..., a

n

) jest na szczycie

stosu, to wynikiem operacji PUSH (S, x) będzie sekwencja:

(a

1

, a

2

, ..., a

n

, x).

2.

Analogicznie, w wyniku operacji POP (S) otrzymamy:

(a

1

, a

2

, ..., a

n-1

).

Zdejmowanie z pustego stosu generuje błąd.

ASD

LJ

S

background image

21

















































Reprezentacja dowiązaniowa stosu

S = (a

1

, a

2

, ..., a

n

)

ASD

LJ

S

Element struktury danych stosu

(

node

)

key

next

a

1

S.top

. . .

a

n

a

n-1

/

Reprezentacja tablicowa stosu

A[1]
A[2]

.
.
.

A[n]

.
.
.

maxLenght

S.top

obszar
zajęty

obszar
wolny

Tablica A reprezentująca stos S=(a

1

, a

2

, ..., a

n

)

typedef struct {

int A[maxLenght];
int top;

} STACK;

STACK *S

ASD

LJ

S

background image

22

















































Reprezentacja tablicowa stosu

Podstawowe operacje.

 Wstawianie elementu na stos.

PUSH(S,x)
{

S.top=S.top+1;
S.A[S.top]=x;

}

 Usuwanie elementu ze stosu.

POP(S)
{

IF (EMPTY(S))

retun(”błąd”);

ELSE{

S.top=S.top-1;
retun(S.top);

}

}

A

S.top

10

4

8

2

A

10

4

8

2

S.top

ASD

LJ

S

S.top

A

10

4

8

2

5

PUSH(S,5)

S.top

A

10

4

8

2

POP(S)

Reprezentacja tablicowa stosu

Podstawowe operacje.

// Czy stos pełny?

EMPTY(S)
{

return(S.top < 1);

}

// Czy stos pełny?

FULL(S)
{

return(S.top ≥ maxLenght);

}

// Zwracanie elementu ze stosu

TOP(S)
{

IF (EMPTY(S))

return(”błąd”);

ELSE

retun(S.A[S.top]);

}

ASD

LJ

S

background image

23















































Kolejka

Queue

Kolejka

Kolejka - dynamiczna struktura danych, oparta na modelu listy i zorganizowana

według zasady FIFO (

First-in First-out

).

Interfejs kolejki:

1. DEQUEUE – usuwanie elementu z początku kolejki

2. ENQUEUE – wstawianie elementu na koniec kolejki

3. EMPTY – sprawdzenie czy kolejka jest pusta

4. FRONT – zwracanie pierwszego elementu

5. CLEAR – tworzenie kolejki pustej

ASD

LJ

S

background image

24















































Wskaźnikowa reprezentacja kolejki

 Q.front - wskazuje na początek kolejki (niezbędny do wykonywania operacji:

FRONT, DEQUEUE, EMPTY),

 Q.rear - wskazuje na koniec kolejki (niezbędny do wykonywania operacji:

ENQUEUE, EMPTY).

Q.front

/

Q.rear

. . .

ASD

LJ

S

Interfejs kolejki

Wstawianie elementu na koniec kolejki.
(Pseudokod).

ENQUEUE(Q,x)
{

Q.rear.next=x;
x.next=NULL;
Q.rear=x;

}

Usuwanie elementu z początku kolejki.
(Pseudokod).

DEQUEUE(Q)
{

IF(EMPTY(Q))

return(0);

ELSE

Q.front=Q.front.next;

}

Czy kolejka jest pusta?.
(Pseudokod).

EMPTY(Q)
{

return(Q.rear == Q.front)

}

ASD

LJ

S

background image

25















































Kolejka cykliczna

Tablicowa implementacja kolejki.

2

1

5

2

6

3

11

4

3

5

9

6

0

7

1

8

8

9

10

Q.front

Q.rear

ASD

LJ

S

typedef struct {

int A[maxLenght];
int front,rear;

} QUEUE;

QUEUE *Q;

Kolejka cykliczna

Elementy kolejki znajdują się na pozycjach: front, front+1, ..., rear-1.

2

1

5

2

6

3

11

4

3

5

9

6

0

7

1

8

8

9

10

front

rear

a)

A

2

1

5

2

6

3

11

4

5

9

6

0

7

1

8

8

9

7

10

rear front

b)

A

 Kolejka pełna: Q.front = (Q.rear mod maxLength + 1)

ASD

LJ

S

background image

26















































Kolejka cykliczna

1

2

6

3

11

4

3

5

9

6

0

7

8

9

10

front

rear

c)

A

11

1

5

2

3

4

5

6

7

6

8

8

9

7

10

d)

front

rear

A

2

1

5

2

6

3

11

4

10

5

9

6

0

7

1

8

8

9

7

10

rear

front

e)

A

ASD

LJ

S

 Kolejka pusta: Q.front = Q.rear

Kolejka cykliczna

Interfejs kolejki cyklicznej.

CYCLE(k)
{

return(k mod maxlength+1)

}

ENQUEUE(Q,x)
{

IF (CYCLE(Q.rear)==Q.front)

return(error); // kolejka pełna

ELSE{

Q.A[Q.rear]= x;
Q.rear=CYCLE(Q.rear);

}

}

ASD

LJ

S

background image

27










































Kolejka cykliczna

Interfejs kolejki cyklicznej.

DEQUEUE(Q)
{

IF (Q.front == Q.rear)

return(error); // kolejka pusta

ELSE

Q.front=CYCLE(Q.front);

}

EMPTY(Q)
{

return(Q.front == Q.rear);

}

Funkcje ENQUEUE, DEQUEUE działają w czasie O(1).

ASD

LJ

S


Wyszukiwarka

Podobne podstrony:
nw asd w13
ASD w5
nw asd w6
nw asd w3
nw asd w12
nw asd w8
nw asd w4
nw asd w2
nw asd w10
ASD W5
nw asd w7
nw asd w9
nw asd w2
nw asd w13
ASD w5

więcej podobnych podstron