Serwis Edukacyjny w I-LO w Tarnowie ![]() Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej Autor artykułu: mgr Jerzy Wałaszek |
©2023 mgr Jerzy Wałaszek |
SPIS TREŚCI |
Tematy pomocnicze |
Podrozdziały |
Do utworzenia stosu w tablicy potrzebujemy dwóch zmiennych. Pierwszą z nich będzie tablica, która przechowuje umieszczone na stosie elementy. Druga zmienna sptr służy do zapamiętywania pozycji szczytu stosu i nosi nazwę wskaźnika stosu (ang. stack pointer ). Umawiamy się, że wskaźnik stosu zawsze wskazuje pustą komórkę tablicy, która znajduje się tuż ponad szczytem stosu:
Po utworzeniu tablicy zmienna sptr musi zawsze być zerowana. Stos jest pusty, gdy sptr wskazuje początek tablicy, czyli komórkę o indeksie zero. Ta własność jest wykorzystywana w operacji empty. Stos jest pełny, gdy sptr ma wartość równą liczbie komórek tablicy. W takim przypadku na stosie nie można już umieszczać żadnych dalszych danych. gdyż trafiłyby poza obszar zarezerwowany na tablicę.
sptr | – | zmienna przechowująca wskaźnik stosu tablicy |
True, jeśli na stosie nie ma żadnego elementu, inaczej false
K01 | Jeśli sptr = 0, to zakończ z wynikiem true |
K02: | Zakończ z wynikiem false |
Pascalfunction empty : boolean; begin if sptr = 0 then empty := true else empty := false; end; |
C++bool empty ( void ) { return !sptr; } |
BasicFunction empty( ) As Integer If sptr = 0 Then Return 1 Return 0 End Function |
sptr | – | zmienna przechowująca wskaźnik stosu tablicy |
n | – | rozmiar tablicy |
S | – | tablica przechowująca stos |
Zawartość szczytu stosu lub wartość specjalna, jeśli stos jest pusty.
K01 | Jeśli sptr = 0, o zakończ z wynikiem wartość specjalna |
K02: | Zakończ z wynikiem S [ sptr - 1 ] |
Pascalfunction top : typ_danych; begin if sptr = 0 then top := wartość_specjalna else top := S [ sptr - 1 ]; end; |
C++typ_danych top ( void ) { if( sptr ) return S [ sptr - 1 ); return wartość_specjalna } |
BasicFunction top( ) As typ_danych If sptr = 0 Then Return wartość_specjalna Return S ( sptr - 1 ) End Function |
sptr | – | zmienna przechowująca wskaźnik stosu tablicy |
n | – | rozmiar tablicy |
S | – | tablica przechowująca stos |
v | – | zapisywana wartość |
Na stosie zostaje zapisana wartość v, jeśli jest na to miejsce. W przeciwnym razie v nie będzie zapisane.
K01 | Jeśli sptr = n, to zakończ |
stos jest pełny i nie ma miejsca na nową wartość |
K02: | S [ sptr ] ← v | umieszczamy v ponad szczytem stosu |
K03: | sptr ← sptr + 1 | zwiększamy wskaźnik stosu |
K04: | Zakończ |
Pascalprocedure push ( v : typ_danych ); begin if sptr < n then begin S [ sptr ] := v; Inc ( sptr ); end; end; |
C++void push ( typ_danych v ) { if( sptr < n ) S [ sptr++ ] = v; } |
BasicSub push ( v As typ_danych ) If sptr < n Then S ( sptr ) = v sptr += 1 End If End Sub |
sptr | – | zmienna przechowująca wskaźnik stosu tablicy |
S | – | tablica przechowująca stos |
Ze szczytu stosu zostaje usunięty element.
K01 | Jeśli sptr > 0, to sptr ← sptr - 1 |
jeśli stos coś zawiera, to usuwamy element na szczycie stosu |
K02: | Zakończ |
Pascalprocedure pop; begin if sptr > 0 then dec ( sptr ); end; |
C++void pop ( void ) { if( sptr ) sptr--; } |
BasicSub pop( ) If sptr > 0 Then sptr -= 1 End Sub |
Uwaga:
Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
Poniższy program przedstawia sposób implementacji stosu w tablicy. Tworzy on obiekt zawierający tablicę liczb całkowitych, wskaźnik stosu oraz metody obsługi tej struktury. Rozmiar tablicy jest określany przy tworzeniu obiektu. Na stosie zostaje zapisanych 10 liczb, a następnie są one odczytywane i wyświetlane. |
Pascal// Stos w tablicy // Data: 13.08.2012 // (C)2020 mgr Jerzy Wałaszek //------------------------------ program arrstack; type Tinteger = array of integer; // Definicja typu obiektowego stack //--------------------------------- stack = object private n : integer; // rozmiar tablicy sptr : integer; // wskaźnik stosu S : Tinteger; // tablica dynamiczna public constructor init ( x : integer ); destructor destroy; function empty : boolean; function top : integer; procedure push ( v : integer ); procedure pop; end; //--------------------- // Metody obiektu stack //--------------------- // Konstruktor - tworzy tablicę dla stosu //--------------------------------------- constructor stack.init ( x : integer ); begin n := x; SetLength ( S, x ); sptr := 0; end; // Destruktor - zwalnia tablicę dynamiczną //---------------------------------------- destructor stack.destroy; begin SetLength ( S, 0 ); end; // Sprawdza, czy stos jest pusty //------------------------------ function stack.empty : boolean; begin if sptr = 0 then empty := true else empty := false; end; // Zwraca szczyt stosu. // Wartość specjalna to -MAXINT //----------------------------- function stack.top : integer; begin if sptr = 0 then top := -MAXINT else top := S [ sptr - 1 ]; end; // Zapisuje na stos //----------------- procedure stack.push ( v : integer ); begin if sptr < n then begin S [ sptr ] := v; Inc ( sptr ); end; end; // Usuwa ze stosu //--------------- procedure stack.pop; begin if sptr > 0 then dec ( sptr ); end; //--------------- // Program główny //--------------- var S : stack; i : integer; begin S.init ( 10 ); for i := 1 to 10 do S.push ( i ); while not S.empty do begin writeln ( S.top ); S.pop; end; S.destroy; end. |
C++// Stos w tablicy // Data: 13.08.2012 // (C)2020 mgr Jerzy Wałaszek //------------------------------ #include <iostream> using namespace std; const int MAXINT = -2147483647; // Definicja typu obiektowego stack //--------------------------------- class stack { private: int n; // rozmiar tablicy int sptr; // wskaźnik stosu int * S; // tablica dynamiczna public: stack ( int x ); // konstruktor ~stack( ); // destruktor bool empty ( void ); int top ( void ); void push ( int v ); void pop ( void ); }; //--------------------- // Metody obiektu stack //--------------------- // Konstruktor - tworzy tablicę dla stosu //--------------------------------------- stack::stack ( int x ) { n = x; S = new int [ x ]; sptr = 0; } // Destruktor - zwalnia tablicę dynamiczną //---------------------------------------- stack::~stack( ) { delete [ ] S; } // Sprawdza, czy stos jest pusty //------------------------------ bool stack::empty ( void ) { return !sptr; } // Zwraca szczyt stosu. // Wartość specjalna to -MAXINT //----------------------------- int stack::top ( void ) { if( sptr ) return S [ sptr - 1 ]; return -MAXINT; } // Zapisuje na stos //----------------- void stack::push ( int v ) { if( sptr < n ) S [ sptr++ ] = v; } // Usuwa ze stosu //--------------- void stack::pop ( void ) { if( sptr ) sptr--; } //--------------- // Program główny //--------------- int main( ) { stack S ( 10 ); // tworzymy stos na 10 elementów int i; for( i = 1; i <= 10; i++ ) S.push ( i ); while( !S.empty( ) ) { cout << S.top( ) << endl; S.pop( ); } } |
Basic' Stos w tablicy ' Data: 13.08.2012 ' (C)2020 mgr Jerzy Wałaszek '------------------------------ Const MAXINT = 2147483647 ' Definicja typu obiektowego stack '--------------------------------- Type stack Private: n As Integer ' rozmiar tablicy sptr As Integer ' wskaźnik stosu S As Integer Ptr ' tablica dynamiczna Public: Declare Constructor ( ByVal x As Integer ) Declare Destructor( ) Declare Function empty( ) As Integer Declare Function top As Integer Declare Sub push ( ByVal v As Integer ) Declare Sub pop( ) End Type '--------------- ' Program główny '--------------- Dim S As stack = 10 Dim i As Integer For i = 1 To 10: S.push ( i ): Next While S.empty( ) = 0 Print S.top( ) S.pop( ) Wend End '--------------------- ' Metody obiektu stack '--------------------- ' Konstruktor - tworzy tablicę dla stosu '--------------------------------------- Constructor stack ( ByVal x As Integer ) n = x S = New Integer [ x ] sptr = 0 End Constructor ' Destruktor - zwalnia tablicę dynamiczną '---------------------------------------- Destructor stack( ) Delete [ ] S End Destructor ' Sprawdza, czy stos jest pusty '------------------------------ Function stack.empty( ) As Integer If sptr = 0 Then Return 1 Return 0 End Function ' Zwraca szczyt stosu. ' Wartość specjalna to -MAXINT '----------------------------- Function stack.top( ) As Integer If sptr = 0 Then Return -MAXINT Return S [ sptr - 1 ] End Function ' Zapisuje na stos '----------------- Sub stack.push ( ByVal v As Integer ) If sptr < n Then S [ sptr ] = v sptr += 1 End If End Sub ' Usuwa ze stosu '--------------- Sub stack.pop( ) If sptr > 0 Then sptr -= 1 End Sub |
Wynik: |
10 9 8 7 6 5 4 3 2 1 |
Do realizacji stosu możemy w prosty sposób wykorzystać listę jednokierunkową. Zapis na stos będzie wtedy polegał na umieszczaniu elementu na początku listy. Szczyt stosu będzie pierwszym elementem listy. Odczyt ze stosu będzie równoważny odczytowi pierwszego elementu listy, a usunięcie ze stosu będzie odpowiadało usunięciu elementu z początku listy. Realizacja listowa jest szczególnie wygodna wtedy, gdy nie znamy maksymalnego rozmiaru stosu – w przeciwieństwie do tablic listy mogą swobodnie rosnąć w pamięci, dopóki jest dla nich miejsce. W podanych niżej procedurach nie obsługujemy sytuacji braku pamięci – w każdym ze środowisk programowania można w takim przypadku wykorzystać mechanizmy wyłapywania błędów, które jednakże zaciemniają realizowane funkcje.
Każdy element listy jest następującą strukturą danych:
Pascaltype PslistEl = ^slistEl; slistEl = record next : PslistEl; data : typ_danych; end; |
C++struct slistEl { slistEl * next; typ_danych data; }; |
BasicType slistEl next As slistEl Ptr data As typ_danych End Type |
Pascal... var stack : PslistEl; ... |
C++... slistEl * stack; ... |
Basic... Dim stack As slistEl Ptr ... |
Przed pierwszym użyciem wskaźnik stack musi być odpowiednio wyzerowany:
Pascal... stack := NIL; ... |
C++... stack = NULL; ... |
Basic... stack = 0 ... |
p | – | wskaźnik szczytu stosu |
True, jeśli na stosie nie ma żadnego elementu, inaczej false
K01 | Jeśli p = nil, to zakończ z wynikiem true |
K02: | Zakończ z wynikiem false |
Pascalfunction empty ( p : PslistEl ) : boolean; begin if p = nil then empty := true else empty := false; end; |
C++bool empty ( slistEl * p ) { return !p; } |
BasicFunction empty ( p As slistEl Ptr ) As Integer If p = 0 Then Return 1 Return 0 End Function |
p | – | wskaźnik szczytu stosu |
Zwraca wskazanie elementu, który jest bieżącym szczytem stosu lub nil, jeśli stos jest pusty
K01: | Zakończ z wynikiem p |
Pascalfunction top ( p : PslistEl ) : PslistEl; begin top := p; end; |
C++slist * top ( slistEl * p ) { return p; } |
BasicFunction top ( p As slistEl Ptr ) As slistEl Ptr Return p End Function |
p | – | wskaźnik szczytu stosu |
v | – | zapisywana wartość |
Na stosie zostaje zapisana wartość v, jeśli jest na to miejsce. Inaczej nic nie zostaje zapisane.
e | – | wskaźnik elementu listy |
K01 | Utwórz element listy i umieść jego adres w e | |
K02: | e→data ← v | dane umieszczamy w polu data |
K03: | e→next ← p | następnikiem będzie bieżący szczyt stosu |
K04: | p ← e | szczytem stosu staje się dodany element |
K05: | Zakończ |
Pascalprocedure push ( var p : PslistEl; v : typ_danych ); var e : PslistEl; begin new ( e ); e^.data := v; e^.next := p; p := e; end; |
C++void push ( slistEl * & p, typ_danych v ) { slistEl * e = new slistEl; e->data = v; e->next = p; p = e; } |
BasicSub push ( ByRef p As slistEl Ptr, v As typ_danych ) Dim e As slistEl Ptr e = New slistEl e->data = v e->next = p p = e End Sub |
p | – | wskaźnik szczytu stosu |
Ze szczytu stosu zostaje usunięty element.
e | – | wskaźnik elementu listy |
K01 | Jeśli p = nil, to zakończ |
stos jest pusty |
K02: | e ← p | zapamiętujemy szczyt stosu |
K03 | p ← p→next | usuwamy ze stosu bieżący szczyt |
K04: | Usuń z pamięci element wskazany przez e | |
K05: | Zakończ |
Pascalprocedure pop ( var p : PslistEl ); var e : PslistEl; begin if p <> nil then begin e := p; p := p^.next; dispose ( e ); end end; |
C++void pop ( slistEl * & p ) { if( p ) { slistEl * e = p; p = p->next; delete e; } } |
BasicSub pop ( ByVal p as slistEl Ptr ) Dim e As slistEl Ptr If p Then e = p p = p->next Delete e End If End Sub |
Uwaga:
Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
Poniższy program przedstawia sposób implementacji stosu za pomocą listy jednokierunkowej. Tworzy on obiekt zawierający pustą listę liczb całkowitych oraz metody obsługi tej struktury. Na stosie zostaje zapisanych 10 liczb, a następnie są one odczytywane i wyświetlane. |
Pascal// Stos na liście jednokierunkowej // Data: 13.08.2012 // (C)2020 mgr Jerzy Wałaszek //------------------------------ program slist_stack; // Typ elementów listy //-------------------- type PslistEl = ^slistEl; slistEl = record next : PslistEl; data : integer; end; // Definicja typu obiektowego stack //--------------------------------- stack = object private S : PslistEl; // lista przechowująca stos public constructor init; destructor destroy; function empty : boolean; function top : PslistEl; procedure push ( v : integer ); procedure pop; end; //--------------------- // Metody obiektu slist //--------------------- // Konstruktor //------------ constructor stack.init; begin S := nil; end; // Destruktor //----------- destructor stack.destroy; begin while S <> nil do pop; end; // Sprawdza, czy stos jest pusty //------------------------------ function stack.empty : boolean; begin if S = nil then empty := true else empty := false; end; // Zwraca wskazanie do szczytu stosu //---------------------------------- function stack.top : PslistEl; begin top := S; end; // Umieszcza dane na stosie //------------------------- procedure stack.push ( v : integer ); var e : PslistEl; begin new ( e ); e^.data := v; e^.next := S; S := e; end; // Usuwa dane ze stosu //-------------------- procedure stack.pop; var e :PslistEl; begin if S <> NIL then begin e := S; S := S^.next; dispose ( e ); end; end; //--------------- // Program główny //--------------- var S : stack; i : integer; begin S.init; for i := 1 to 10 do S.push ( i ); while not S.empty do begin writeln ( S.top^.data ); S.pop; end; S.destroy; end. |
C++// Stos na liście jednokierunkowej // Data: 13.08.2012 // (C)2020 mgr Jerzy Wałaszek //------------------------------ #include <iostream> using namespace std; // Definicja typu obiektowego stack //--------------------------------- struct slistEl { slistEl * next; int data; }; class stack { private: slistEl * S; // lista przechowująca stos public: stack( ); // konstruktor ~stack( ); // destruktor bool empty ( void ); slistEl * top ( void ); void push ( int v ); void pop ( void ); }; //--------------------- // Metody obiektu stack //--------------------- // Konstruktor //------------ stack::stack( ) { S = NULL; } // Destruktor - zwalnia tablicę dynamiczną //---------------------------------------- stack::~stack( ) { while( S ) pop( ); } // Sprawdza, czy stos jest pusty //------------------------------ bool stack::empty ( void ) { return !S; } // Zwraca szczyt stosu //-------------------- slistEl * stack::top ( void ) { return S; } // Zapisuje na stos //----------------- void stack::push ( int v ) { slistEl * e = new slistEl; e->data = v; e->next = S; S = e; } // Usuwa ze stosu //--------------- void stack::pop ( void ) { if( S ) { slistEl * e = S; S = S->next; delete e; } } //--------------- // Program główny //--------------- int main( ) { stack S; int i; for( i = 1; i <= 10; i++ ) S.push ( i ); while( !S.empty( ) ) { cout << S.top( )->data << endl; S.pop( ); } } |
Basic' Stos na liście jednokierunkowej ' Data: 13.08.2012 ' (C)2020 mgr Jerzy Wałaszek '------------------------------ ' Definicja typu obiektowego stack '--------------------------------- Type slistEl next As slistEl Ptr data As Integer End Type Type stack Private: S As slistEl Ptr ' lista zawierająca stos Public: Declare Constructor( ) Declare Destructor( ) Declare Function empty( ) As Integer Declare Function top As slistEl Ptr Declare Sub push ( ByVal v As Integer ) Declare Sub pop( ) End Type '--------------- ' Program główny '--------------- Dim S As stack Dim i As Integer For i = 1 To 10: S.push ( i ): Next While S.empty( ) = 0 Print S.top( )->Data S.pop( ) Wend End '--------------------- ' Metody obiektu stack '--------------------- ' Konstruktor '------------ Constructor stack( ) S = 0 End Constructor ' Destruktor '----------- Destructor stack( ) While S pop( ) Wend End Destructor ' Sprawdza, czy stos jest pusty '------------------------------ Function stack.empty( ) As Integer If S = 0 Then Return 1 Return 0 End Function ' Zwraca szczyt stosu. '------------------------------ Function stack.top( ) As slistEl Ptr top = S End Function ' Zapisuje na stos '----------------- Sub stack.push ( ByVal v As Integer ) Dim e As slistEl Ptr e = New slistEl e->Data = v e->Next = S S = e End Sub ' Usuwa ze stosu '--------------- Sub stack.pop( ) Dim e As slistEl Ptr If S Then e = S S = S->Next Delete e End If End Sub |
Wynik: |
10 9 8 7 6 5 4 3 2 1 |
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2023 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.