ARCHIV |
|||||
Software (10844)
Distribuce (131)
Skripty (697)
Menu
Diskuze
Informace
|
C++ Datová struktura zásobníkV tomto článku se podíváme na to, co je to zásobník, jak funguje a jak jej lze naimplementovat. Ukážeme
si také krátký příklad, ve kterém zásobník využijeme. Veškerá implementace bude provedena v jazyce C++,
proto se předpokládá alespoň základní znalost syntaxe a znalost objektově orientovaného programování. Co je to zásobník a jak fungujeZásobník, neboli anglicky stack, je datová struktura, u níž je přesně určen způsob přidávání a odebírání prvků. U zásobníku je uplatněn způsob LIFO (last in, first out), česky "první dovnitř, poslední ven". Přesným opakem zásobníku je fronta, kde je uplatně způsob FIFO (first in, first out), o tom ale článek není. Pro lepší pochopení, jak zásobník funguje, si představte zásobník u pistole. Budeme-li do tohoto zásobníku ukládat náboje, vezmeme první, dáme jej do zásobníku a náboj spadne na dno zásobníku. Vezmeme druhý náboj, vložíme do zásobníku a druhý náboj zůstane ležet na prvním náboji. Celý tento postup opakujeme do doby, než bude zásobník pistole plný. Poslední náboj, který jsme do pistole vložili, bude tedy v zásobníku úplně nahoře. Způsob přidávání prvků do zásobníku jakožto do datové struktury je úplně stejný. Co se týče odebírání prvků ze zásobníku, opět jde o stejný způsob jako o odebrání (vystřelení) náboje ze zásobníku pistole. Vložíme-li zásobník do pistole a stiskneme-li spoušť, jako první vyletí námi naposledy přidaný náboj. Náboj, který jsme vložili jako první, přijde na řadu až jako poslední. V tom je tedy ukryt onen způsob LIFO. Námi první vložený náboj opustí zásobník až jako poslední a není jiná možnost, jak jej vyjmout předtím, než odstraníme náboje nad ním. Nyní se seznámíme s několika pojmy, které se u zásobníku používají. Začneme ukazatelem na aktální prvek v zásobníku (to je ten, který jsme vložili jako poslední, čili je na vrcholu zásobníku), který se nazývá vrchol zásobníku, anglicky stack pointer. Metoda, určená pro přidávání prvků do zásobníku, se většinou nazývá push. Metodu, která se stará o vyjmutí prvků, nazýváme nejčastěji pop. Počet prvků v zásobníku je víceméně neomezený, jedinným omezením nám může být paměť počítače. Jak lze zásobník implementovatZpůsob, jak implementovat zásobník, není víceméně dán nějak striktně, důležité pouze je, aby splňoval vlastnosti, které jsme si uvedli výše. Proto řešení, které uvádím zde, rozhodně není jediné, možností je více. Moje řešení spočívá v tom, že jsem si napsal třídu Stack, která vypadá takto:Takto jednoduše by mohla vypadat třída, reprezentující zásobník. Do tohoto zásobníku je možné ukládat pouze čísla typu int, nicméně pro pochopení by to mělo stačit. Věřím, že po přečtení článku budete schopni sami implementovat zásobník, do kterého bude možno uložit něco jiného.
Členská proměnná stackPointer si pamatuje číslo prvku, který byl přidán naposled. Slouží tedy jako vrchol zásobníku.
Pointer items ukazuje na pole prvků zásobníku (v tuto chvíli ještě ne, po zavolání konstruktoru třídy však ano). Do proměnné
maxSize se uloží velikost zásobníku. Nyní se tedy podívejme na těla metod a na tělo konstruktoru. Konstruktor má jeden parametr, který určuje maximální velikost zásobníku. Tato hodnota se uloží do proměnné maxSize. Dále se v konstruktoru stanou dvě věci - alokuje se pole typu int o velikosti maxSize a proměnná stackPointer se nastaví na nulu, neboť právě vytvořený zásobník neobsahuje žádný prvek. Co se týče metody push, není na ní nic těžkého. Do pole items se uloží prvek x a hodnota proměnné stackPointer se zvýší o jedničku. Stejně jednoduchá jako metoda Push je jednoduchá i metoda Pop. Hodnota proměnné stackPointer se snižuje o jedničku, neboť prvek vyzvedáváme ze zásobníku. Všimněte si, že vyjmutý prvek v poli zůstane, nebude možné k němu však již přistoupit a při přidání nového prvku se tento prvek přepíše. V obou metodách je přidána podmínka, která ověřuje, jestli zásobník není prázdný, resp. plný. Zásobník v praxiPevně věřím tomu, že jste pochopili, jak zásobník funguje a jak jej lze implementovat. Nezmínil jsem se však, kdy se nám zásobník může hodit. Úplně jednoduchým příkladem může být program, který umí vyhodnotit výraz v postfixové notaci. Pokud nevíte, jak postfixová notace vypadá, doporučuji se podívat zde.
Velmi zjednodušeně by se dal algoritmus popsat takto: celý řetězec (řetezcem je myšlen uživatelem zadaný výraz) si rozložíme
na jednotlivá čísla a operátory, přičemž je
budeme postupně procházet. Přečteme tedy první znak (buď číslo, nebo operátor) a pokud to bude číslo, uložíme jej na zásobník.
V opačném případě se musí jednat o operátor, což pro nás znamená, že musíme provést nějakou operaci (záleží na tom, o jaký
operátor se bude jednat). Předpokládejme, že se jedná o operátor plus. Vyzvedeme tedy ze zásobníku dvě čísla, která sečteme a
výsledek uložíme zpět na zásobník. Celý tento postup budeme opakovat tak dlouho, dokud neprojdeme celý, uživatelem zadaný
řetězec. Výsledek celého výrazu bude uložen v zásobníku. Zavoláme tedy metodu Pop a získáme konečný výsledek. Pro
dokonalé pochopení si zkusme nyní vyhodnotit výraz 3 5 + 4 -.
Související články
Předchozí Celou kategorii (seriál) Další
C/C++ (1) - Úvod
C/C++ (2) - První program C/C++ (3) - Proměnné a konstanty C/C++ (4) - Funkce printf C/C++ (5) - Funkce printf podruhé C/C++ (6) - Operátory C/C++ (7) - Podmínka C/C++ (8) - Cykly C/C++ (9) - Pole C/C++ (10) - Standardní vstup a výstup C/C++ (11) - Čtení a konverze čísel C/C++ (12) - Preprocesor C/C++ (13) - Preprocesor podruhé C/C++ (14) - Funkce C/C++ (15) - Proměnné C/C++ (16) - Hlavičkové soubory C/C++ (17) - Makefile C/C++ (18) - Makefile podruhé C/C++ (19) - Příkaz switch a bitové operátory C/C++ (20) - Alokace paměti C/C++ (21) - Práce s řetězci C/C++ (22) - Struktury C/C++ (23) - Seznam C/C++ (24) - Soubory C/C++ (25) - Funkce s proměnným počtem parametrů C/C++ (26) - Standardní knihovna C/C++ (27) - Standardní knihovna podruhé C/C++ (28) - Standardní knihovna potřetí C/C++ (29) - Standardní knihovna počtvrté C/C++ (30) - Výčtový typ a nestandardní knihovny C/C++ (31) - Jazyk C++, historie, charakteristika, vztah k C C/C++ (32) - Omezení C++ oproti C C/C++ (33) - Rozdíly mezi C a C++ C/C++ (34) - Drobná vylepšení C++ C/C++ (35) - Reference, funkce C/C++ (36) - Prostory jmen C/C++ (37) - Prostory jmen podruhé C/C++ (38) - Prostory jmen potřetí C/C++ (39) - Objektově orientované programování C/C++ (40) - Dědičnost a virtuální metody GCC vs. CLANG C++ Binární vyhledávací stromy C++ - Hashování C++ - Vyhledávání v textu - Brute Force algoritmus C++ šablony Grafy a grafové algoritmy I Grafy a grafové algoritmy II C++ výjimky C++ Funktory neboli funkční objekty Grafy a grafové algoritmy III. C++ a garbage collector Předchozí Celou kategorii (seriál) Další
|
Vyhledávání software
Vyhledávání článků
28.11.2018 23:56 /František Kučera 12.11.2018 21:28 /Redakce Linuxsoft.cz 6.11.2018 2:04 /František Kučera 4.10.2018 21:30 /Ondřej Čečák 18.9.2018 23:30 /František Kučera 9.9.2018 14:15 /Redakce Linuxsoft.cz 12.8.2018 16:58 /František Kučera 16.7.2018 1:05 /František Kučera
Poslední diskuze
31.7.2023 14:13 /
Linda Graham 30.11.2022 9:32 /
Kyle McDermott 13.12.2018 10:57 /
Jan Mareš 2.12.2018 23:56 /
František Kučera 5.10.2018 17:12 /
Jakub Kuljovsky | |||
ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2024) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze |