• Nie Znaleziono Wyników

Stos

N/A
N/A
Protected

Academic year: 2021

Share "Stos"

Copied!
47
0
0

Pełen tekst

(1)

Algorytmy i struktury danych

Algorytmy i struktury danych

Roman Simiński

roman.siminski@us.edu.pl roman@siminskionline.pl programowanie.siminskionline.pl

Stos

Stos

Rozważania implementacyjne

Rozważania implementacyjne

(2)

Stos – koncepcja

Stos – koncepcja

Pusty

Coś do położenia na stos

(3)

Stos – koncepcja, cd. ...

Stos – koncepcja, cd. ...

Pusty

Coś zdjęte ze stosu

(4)

Stos, operacje: połóż (push)

Stos, operacje: połóż (push)

Szczyt stosu

Szczyt stosu

(5)

Stos, operacje: zdejmij (pop)

Stos, operacje: zdejmij (pop)

Szczyt stosu

Szczyt stosu

Zdjęty element

(6)

Stos, operacje zabronione

Stos, operacje zabronione

(7)

Stos, operacja dodatkowa: pobierz, szczyt (peek, top)

Stos, operacja dodatkowa: pobierz, szczyt (peek, top)

Szczyt stosu

Pobierz

Pobierz kopię elementu ze szczytu nie zdejmując go ze stosu.

Inaczej: sprawdź co jest na szczycie stosu

Pobierz kopię elementu ze szczytu nie zdejmując go ze stosu.

Inaczej: sprawdź co jest na szczycie stosu

(8)

Stos, pożądany interfejs

Stos, pożądany interfejs

class Stack {

public:

// Najlepiej rozrastał się w miarę potrzeb Stack();

// Ale czasem trzeba albo warto ustalić pożądany rozmiar Stack( int size );

// Podstawowe operacje bool push( Type item ); Type pop();

Type peek();

// Czy stos jest pusty? bool empty();

// Ile aktualnie jest elementów na stosie? int size();

// Czyszczenie stosu void clear();

(9)

Stos: implementacja z wykorzystaniem tablicy

Stos: implementacja z wykorzystaniem tablicy

Szczyt

0 1 . . . 2 3 4

.

.

.

N

Szczyt

0 1 . . . 2 3 4

.

.

.

N

Szczyt

0 1 . . . 2 3 4

.

.

.

N -1

Rozmiar stosu jest ograniczony rozmiarem tablicy. Można jednak

zaimplementować rozszerzanie rozmiaru stosu z wykorzystaniem

Rozmiar stosu jest ograniczony rozmiarem tablicy. Można jednak

zaimplementować rozszerzanie rozmiaru stosu z wykorzystaniem

(10)

Stos: implementacja z wykorzystaniem tablicy

Stos: implementacja z wykorzystaniem tablicy

Szczyt

0 1 . . . 2 3 4

.

.

.

N

Szczyt

0 1 . . . 2 3 4

.

.

.

N

Szczyt

0 1 . . . 2 3 4

.

.

.

N

Dla wygody implementacji zakłada się czasem, że „szczyt” stosu

identyfikuje pierwszy wolny element.

Dla wygody implementacji zakłada się czasem, że „szczyt” stosu

identyfikuje pierwszy wolny element.

(11)

Stos: naiwna implementacja z wykorzystaniem tablicy o stałym rozmiarze

Stos: naiwna implementacja z wykorzystaniem tablicy o stałym rozmiarze

const int MAX_SIZE = 20; class Stack

{

public:

Stack() : top( -1 ) {} bool push( int item ) {

if( top < MAX_SIZE - 1 ) {

items[ ++top ] = item;

return true; } return false; } int pop() { if( empty() )

return INT_MIN; // Co zrobić gdy stos jest pusty? return items[ top-- ];

}

Zakładamy chwilowo, że rozważamy stos liczb całkowitych

Zakładamy chwilowo, że rozważamy stos liczb całkowitych

(12)

Stos: naiwna implementacja z wykorzystaniem tablicy o stałym rozmiarze

Stos: naiwna implementacja z wykorzystaniem tablicy o stałym rozmiarze

. . .

int peek() {

if( empty() )

return INT_MIN; // Co zrobić gdy stos jest pusty? return items[ top ];

}

bool empty() const { return ( top <= -1 ); } int size() const { return top + 1; }

void clear() { top = -1; } protected:

int items[ MAX_SIZE ]; int top;

(13)

Operacja pop – programistyczne rozterki...

Operacja pop – programistyczne rozterki...

. . .

int pop() {

if( empty() )

return INT_MIN; // Nawet gdy stos jest pusty funkcja ma mieć rezultat return items[ top-- ];

}

. . . Stack s;

s.push( 100 );

(14)

Operacja pop – a może...

Operacja pop – a może...

. . .

void pop( int & item ) {

if( !empty() )

item = items[ top-- ]; }

. . .

. . .

bool pop( int & item ) {

if( empty() ) return false; else

{

item = items[ top-- ]; return true; } } . . . Stack s; s.push( 100 ); int number; s.pop( number ); Stack s; s.push( 100 ); int number;

if( s.pop( number ) )

(15)

A może zastosować wyjątki...?

A może zastosować wyjątki...?

. . .

int pop() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW;

return items[ top-- ]; } . . . Stack s; s.push( 100 ); try {

int number = s.pop(); . . .

}

catch( ... ) {

(16)

Najprostsza implementacja z wykorzystaniem wyjątków

Najprostsza implementacja z wykorzystaniem wyjątków

const int STACK_OVERFLOW = 0; const int STACK_UNDERFLOW = 1;

class Stack {

. . .

bool push( int item ) throw( int )

{

if( top == MAX_SIZE - 1 ) throw STACK_OVERFLOW;

items[ ++top ] = item; return true;

}

int pop() throw( int )

{

if( empty() )

throw STACK_UNDERFLOW;

return items[ top-- ]; }

int peek() throw( int )

{

(17)

Obsługa stosu z wykorzystaniem wyjątków

Obsługa stosu z wykorzystaniem wyjątków

try { int number; s.push( 1 ); s.push( 2 ); s.push( 3 ); for( ; ; ) number = s.pop(); }

catch( int & exceptionId ) {

switch( exceptionId ) {

case STACK_OVERFLOW : Reakcja na przepełnienie break;

case STACK_UNDERFLOW : Reakcja na pusty stos break;

} }

(18)

Stos o dynamicznie ustalanym

Stos o dynamicznie ustalanym

rozmiarze

(19)

Tablicę przechowującą elementy stosu można tworzyć dynamicznie

Tablicę przechowującą elementy stosu można tworzyć dynamicznie

const int STACK_OVERFLOW = 0; const int STACK_UNDERFLOW = 1;

const int STACK_NOMEMORY = 2;

const int MAX_SIZE = 20; class Stack

{

public:

Stack( int size = MAX_SIZE ) : top( -1 ), items( 0 ) {

if( size > 0 ) try

{

items = new int[ length = size ];

} catch( ... ) { throw STACK_NOMEMORY; } } ~Stack() {

(20)

Tablicę przechowującą elementy stosu można tworzyć dynamicznie

Tablicę przechowującą elementy stosu można tworzyć dynamicznie

bool push( int item ) throw( int ) {

if( items == 0 || top >= length - 1 ) throw STACK_OVERFLOW;

items[ ++top ] = item; return true;

}

int pop() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; return items[ top-- ]; }

int peek() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; return items[ top ];

}

(21)

Tablicę przechowującą elementy stosu można tworzyć dynamicznie

Tablicę przechowującą elementy stosu można tworzyć dynamicznie

int size() const { return top + 1; } void clear() { if( items ) delete [] items; items = 0; length = 0; } protected: int * items; int top; int length; };

(22)

Czy trzeba będzie

Czy trzeba będzie

implementować stos

implementować stos

dla każdego typu danych?

(23)

Stos z wykorzystaniem szablonów

Stos z wykorzystaniem szablonów

template <class T>

class Stack {

public:

Stack( int size = MAX_SIZE ) : top( -1 ), items( 0 ) {

if( size > 0 ) try

{

items = new T[ length = size ];

} catch( ... ) { throw STACK_NOMEMORY; } } ~Stack() { clear(); }

(24)

Stos z wykorzystaniem szablonów

Stos z wykorzystaniem szablonów

bool push( T item ) throw( int ) {

if( items == 0 || top >= length - 1 ) throw STACK_OVERFLOW;

items[ ++top ] = item; return true;

}

T pop() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; return items[ top-- ]; }

T peek() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; return items[ top ];

(25)

Stos z wykorzystaniem szablonów

Stos z wykorzystaniem szablonów

bool empty() const {

return ( items == 0 || top <= -1 ); }

int size() const { return length; } void clear() { if( items ) delete [] items; items = 0; length = 0; } protected: T * items; int top; int length;

Dla tak zrealizowanego stosu można dodać operację powiększenia rozmiaru tablicy items

gdy stos zostanie zapełniony.

Dla tak zrealizowanego stosu można dodać operację powiększenia rozmiaru tablicy items

(26)

Konkretyzowanie stosów

Konkretyzowanie stosów

struct Point { int x, y }; Stack<int> s1; Stack<double> s2; Stack<int> s3; Stack<Point> s4; Stack<char *> s5;

Uwaga, w języku C++ trzeba pamiętac o zdefiniowaniu konstruktora kopiującego jeżeli

chcemy pamiętac na stosie obiekty alokujące indywidualne zasoby.

Uwaga, w języku C++ trzeba pamiętac o zdefiniowaniu konstruktora kopiującego jeżeli

chcemy pamiętac na stosie obiekty alokujące indywidualne zasoby.

(27)

Implementacja

Implementacja

stosu z wykorzystaniem listy

(28)

Stos jako lista – pusty stos

Stos jako lista – pusty stos

(29)

Stos jako lista – dodanie elementu, etap pierwszy

Stos jako lista – dodanie elementu, etap pierwszy

zawartość

(30)

Stos jako lista – dodanie elementu, etap drugi

Stos jako lista – dodanie elementu, etap drugi

zawartość

(31)

Stos jako lista – dodanie elementu, etap trzeci

Stos jako lista – dodanie elementu, etap trzeci

zawartość

(32)

Stos jako lista – kolejny element

Stos jako lista – kolejny element

zawartość

top

(33)

Stos jako lista – kolejny element

Stos jako lista – kolejny element

zawartość

top

zawartość

(34)

Stos jako lista – kolejny element

Stos jako lista – kolejny element

zawartość

top

zawartość

zawartość

(35)

Stos jako lista – kolejny element

Stos jako lista – kolejny element

zawartość

top

zawartość

zawartość

zawartość

zawartość

(36)

Należy zdefiniować klasę (strukturę) elementu listy

Należy zdefiniować klasę (strukturę) elementu listy

template <typename T> class Stack

{

public:

Stack() : top( 0 ), length( 0 ) { } ~Stack() { clear(); } . . . protected: struct StackItem { T item;

struct StackItem * next; };

(37)

Dodawanie pierwszego elementu do stosu

Dodawanie pierwszego elementu do stosu

bool push( T item ) throw( int ) {

try {

StackItem * newItem = new StackItem;

newItem->item = item; newItem->next = top; top = newItem; length++; return true; } catch( ... ) { throw STACK_NOMEMORY; } } top newItem

(38)

bool push( T item ) throw( int ) {

try {

StackItem * newItem = new StackItem; newItem->item = item; newItem->next = top; top = newItem; length++; return true; } catch( ... ) { throw STACK_NOMEMORY; } }

Dodawanie pierwszego elementu do stosu

Dodawanie pierwszego elementu do stosu

XXX

top

(39)

bool push( T item ) throw( int ) {

try {

StackItem * newItem = new StackItem; newItem->item = item; newItem->next = top; top = newItem; length++; return true; } catch( ... ) { throw STACK_NOMEMORY; } }

Dodawanie pierwszego elementu do stosu

Dodawanie pierwszego elementu do stosu

XXX

top

(40)

bool push( T item ) throw( int ) {

try {

StackItem * newItem = new StackItem; newItem->item = item; newItem->next = top; top = newItem; length++; return true; } catch( ... ) { throw STACK_NOMEMORY; } }

Dodawanie pierwszego elementu do stosu

Dodawanie pierwszego elementu do stosu

XXX

top

(41)

bool push( T item ) throw( int ) {

try {

StackItem * newItem = new StackItem;

newItem->item = item; newItem->next = top; top = newItem; length++; return true; } catch( ... ) { throw STACK_NOMEMORY; } }

Dodawanie kolejnego elementu do stosu

Dodawanie kolejnego elementu do stosu

XXX

top

yyy

xxx newItem

(42)

bool push( T item ) throw( int ) {

try {

StackItem * newItem = new StackItem; newItem->item = item; newItem->next = top; top = newItem; length++; return true; } catch( ... ) { throw STACK_NOMEMORY; } }

Dodawanie kolejnego elementu do stosu

Dodawanie kolejnego elementu do stosu

XXX

top

yyy

xxx newItem

(43)

bool push( T item ) throw( int ) {

try {

StackItem * newItem = new StackItem; newItem->item = item; newItem->next = top; top = newItem; length++; return true; } catch( ... ) { throw STACK_NOMEMORY; } }

Dodawanie kolejnego elementu do stosu

Dodawanie kolejnego elementu do stosu

xxx

top

yyy

(44)

T pop() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; T returnValue = top->item;

StackItem * itemToDelete = top;

top = top->next;

delete itemToDelete; length--;

return returnValue; }

Usuwanie elementu ze stosu

Usuwanie elementu ze stosu

xxx

top

yyy

(45)

T pop() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; T returnValue = top->item;

StackItem * itemToDelete = top; top = top->next;

delete itemToDelete; length--;

return returnValue; }

Usuwanie elementu ze stosu

Usuwanie elementu ze stosu

xxx

top

yyy

(46)

T pop() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; T returnValue = top->item;

StackItem * itemToDelete = top; top = top->next;

delete itemToDelete;

length--;

return returnValue; }

Usuwanie elementu ze stosu

Usuwanie elementu ze stosu

xxx

top

yyy

itemToDelete

(47)

T peek() throw( int ) {

if( empty() )

throw STACK_UNDERFLOW; return top->item;

}

bool empty() const {

return ( top == 0 ); }

int size() const { return length; } void clear() { while( !empty() )

Pozostałe operacje

Pozostałe operacje

Cytaty

Powiązane dokumenty

Jeśli znakiem wyrażenia jest operator, to Usun ze stosu dwie kolejne dane, wykonaj działanie zgodne z operatorem i Wstaw wynik na stos o Jeśli znakiem jest cyfra, Wstaw na

Pali się górne światło i pewnie jeszcze nocna

etyka społeczna dziedzina rozpatrująca stosunek jednostki do grupy lub jej aspiracje oraz dążenia w określonym zespole ludzi, w którymś jakaś osoba

Certaines fêtes sont civiles et d’autre sont d’origine religieuses.. Voici

PRZYKŁADOWE ROZWIĄZANIA I SCHEMAT PUNKTOWANIA Maksymalna liczba punktów: 60..

0 2 Patrz Śliwiński: Prawo karne, C zęść szczególna, s. Stanowisko SN nie wydaje się trafne. Jak już zostało wyżej podniesione, fakt porzucenia zabranej rzeczy nie

two przez zabór określa działanie polegające na wyjęciu mienia spod władztwa osoby władającej mieniem i przeniesienia tego mienia we władztwo sprawcy zaboru.53 Podobnie w

Ostatnią z wyróżnionych grup hackerów jest marginalizowana nieco przez resztę, jed- nak darzona szacunkiem, grupa hackerów legalnych wywodząca się z white hats, której