Bevezetés
Míg egyes adatstruktúrák sokoldalúak, és sokféle alkalmazásban használhatók, mások speciálisak és speciális problémák kezelésére készültek. Az egyik ilyen speciális szerkezet, amely egyszerűségéről és mégis figyelemre méltó hasznosságáról ismert, a verem.
Szóval, mi az a verem? A verem lényegében egy lineáris adatstruktúra, amely követi a LIFO (Last In First Out) elv. Tekintsd úgy, mint egy halom tányért egy kávézóban; csak azt a tányért veszed, ami a tetején van, és új tányér elhelyezésekor az a köteg tetejére kerül.
Az utoljára hozzáadott elem az első elem, amelyet el kell távolítani
De miért fontos a verem megértése? Az évek során a stackek rengeteg területen találták meg alkalmazásukat, a kedvenc programozási nyelvek memóriakezelésétől a webböngésző vissza gombjaiig. Ez a lényegi egyszerűség a széleskörű alkalmazhatóságával párosulva a verem nélkülözhetetlen eszközzé teszi a fejlesztők arzenáljában.
Ebben az útmutatóban részletesen bemutatjuk a veremek mögött rejlő fogalmakat, azok megvalósítását, használati eseteit és még sok mást. Meghatározzuk, hogy melyek a veremek, hogyan működnek, majd megvizsgáljuk a verem-adatstruktúra Pythonban való megvalósításának két leggyakoribb módját.
A verem-adatstruktúra alapfogalmai
A verem lényegét tekintve megtévesztően egyszerű, mégis olyan árnyalatokkal rendelkezik, amelyek sokoldalú alkalmazásokat biztosítanak számára a számítási területen. Mielőtt belemerülnénk a megvalósításba és a gyakorlati felhasználásba, biztosítsuk a veremeket körülvevő alapvető fogalmak sziklaszilárd megértését.
A LIFO (Last In First Out) elv
LIFO ez a vezérelv a verem mögött. Ez azt jelenti, hogy az utolsó elem, amelyik utoljára lép be a verembe, az elsőként távozik. Ez a jellemző megkülönbözteti a veremeket más lineáris adatstruktúráktól, például a várólistáktól.
Jegyzet: Egy másik hasznos példa, amely segíthet a halom működésének fogalmán, hogy képzeljük el, amint az emberek be- és kiszállnak egy lift - aki utoljára lép be a liftbe, az elsőként száll ki!
Alapműveletek
Minden adatszerkezetet az általa támogatott műveletek határoznak meg. A veremeknél ezek a műveletek egyszerűek, de létfontosságúak:
- Nyomja – Elemet ad a verem tetejére. Ha a verem megtelt, ez a művelet verem túlcsordulást eredményezhet.
- Pop – Eltávolítja és visszaküldi a köteg legfelső elemét. Ha a verem üres, a felpattanási kísérlet verem alulcsordulást okozhat.
- Bepillantás (vagy felül) – Megfigyeli a legfelső elemet anélkül, hogy eltávolítaná. Ez a művelet akkor hasznos, ha az aktuális felső elemet a verem állapotának megváltoztatása nélkül szeretné megvizsgálni.
Mára már nyilvánvalóvá kell válnia a verem adatszerkezetének és alapfogalmainak jelentősége. Ahogy haladunk előre, belemerülünk a megvalósításába, és rávilágítunk arra, hogy ezek az alapvető elvek hogyan ültethetők át a gyakorlati kódba.
Hogyan valósíthatunk meg egy veremet a semmiből a Pythonban
Miután felfogtuk a halmok mögött rejlő alapelveket, itt az ideje, hogy feltűrjük az ingujjunkat, és beleássuk magunkat a dolgok gyakorlati oldalába. A verem megvalósítása, bár egyszerű, többféleképpen is megközelíthető. Ebben a részben a verem megvalósításának két elsődleges módszerét vizsgáljuk meg – tömbök és csatolt listák használatával.
Verem megvalósítása tömbök használatával
Tömbök, lét összefüggő memóriahelyek, intuitív módszert kínálnak a halmok ábrázolására. Lehetővé teszik az O(1) időbonyolítást az elemek index általi eléréséhez, biztosítva a gyors push, pop és peek műveleteket. Ezenkívül a tömbök memóriahatékonyabbak lehetnek, mivel nincs több mutató, mint a hivatkozott listákban.
Másrészt a hagyományos tömbök fix méretűek, vagyis az inicializálás után nem méretezhetők át. Ez oda vezethet, hogy a verem túlcsordulás ha nem figyelik. Ez leküzdhető dinamikus tömbökkel (mint például a Python list
), amely átméretezhető, de ez a művelet meglehetősen költséges.
Ha mindez nincs az útban, kezdjük el a veremosztályunk megvalósítását tömbök segítségével Pythonban. Először is hozzunk létre egy osztályt azzal a konstruktorral, amely a verem méretét veszi paraméterként:
class Stack: def __init__(self, size): self.size = size self.stack = [None] * size self.top = -1
Amint látja, három értéket tároltunk az osztályunkban. A size
a verem kívánt mérete, a stack
az a tényleges tömb, amelyet a verem adatszerkezetének ábrázolására használnak, és a top
az utolsó elem indexe a stack
tömb (a verem teteje).
Mostantól minden alapvető veremművelethez létrehozunk és elmagyarázunk egy metódust. Ezen módszerek mindegyikét tartalmazza a Stack
osztályt, amit most hoztunk létre.
Kezdjük a push()
módszer. Amint azt korábban tárgyaltuk, a push művelet hozzáad egy elemet a verem tetejéhez. Először is ellenőrizzük, hogy a veremben van-e szabad hely a hozzáadni kívánt elem számára. Ha megtelt a verem, emeljük a Stack Overflow
kivétel. Ellenkező esetben csak hozzáadjuk az elemet, és beállítjuk a top
és a stack
Eszerint:
def push(self, item): if self.top == self.size - 1: raise Exception("Stack Overflow") self.top += 1 self.stack[self.top] = item
Most meghatározhatjuk a módszert egy elem eltávolítására a verem tetejéről - a pop()
módszer. Mielőtt még megpróbálnánk eltávolítani egy elemet, ellenőriznünk kell, hogy vannak-e elemek a veremben, mert nincs értelme megpróbálni egy elemet üres veremből kiemelni:
def pop(self): if self.top == -1: raise Exception("Stack Underflow") item = self.stack[self.top] self.top -= 1 return item
Végül meghatározhatjuk a peek()
metódus, amely éppen annak az elemnek az értékét adja vissza, amely jelenleg a verem tetején van:
def peek(self): if self.top == -1: raise Exception("Stack is empty") return self.stack[self.top]
És ez az! Most van egy osztályunk, amely a veremek viselkedését a Python listáival valósítja meg.
Verem megvalósítása linkelt listák használatával
Kapcsolt listák, lény dinamikus adatstruktúrák, könnyen nőhet és zsugorodhat, ami előnyös lehet a veremek megvalósításához. Mivel a csatolt listák szükség szerint foglalják le a memóriát, a verem dinamikusan nőhet és csökkenhet anélkül, hogy kifejezett átméretezésre lenne szükség. A csatolt listák használatának másik előnye a veremek megvalósításához, hogy a push és pop műveletek csak egyszerű mutatómódosítást igényelnek. Ennek az a hátránya, hogy a hivatkozott lista minden eleméhez tartozik egy további mutató, ami több memóriát fogyaszt a tömbökhöz képest.
Amint arról már beszéltünk a „Python linkelt listák” cikkben, az első dolog, amit a tényleges linkelt lista előtt megvalósítanunk kell, egy osztály egyetlen csomóponthoz:
class Node: def __init__(self, data): self.data = data self.next = None
Tekintse meg gyakorlatias, gyakorlati útmutatónkat a Git tanulásához, amely tartalmazza a bevált gyakorlatokat, az iparág által elfogadott szabványokat és a mellékelt csalólapot. Hagyd abba a guglizást a Git parancsokkal, és valójában tanulni meg!
Ez a megvalósítás csak két adatpontot tárol – a csomópontban tárolt értéket (data
) és a hivatkozás a következő csomópontra (next
).
3 részes sorozatunk a Python linkelt listáiról:
Most ráugorhatunk magára a veremosztályra. A kivitelező kicsit más lesz, mint az előző. Csak egy változót fog tartalmazni – a verem tetején lévő csomópontra való hivatkozást:
class Stack: def __init__(self): self.top = None
Ahogy az várható volt, a push()
metódus egy új elemet (ebben az esetben csomópontot) ad hozzá a verem tetejéhez:
def push(self, item): node = Node(item) if self.top: node.next = self.top self.top = node
A pop()
metódus ellenőrzi, hogy vannak-e elemek a veremben, és eltávolítja a legfelsőt, ha a verem nem üres:
def pop(self): if not self.top: raise Exception("Stack Underflow") item = self.top.data self.top = self.top.next return item
Végül a peek()
A metódus egyszerűen kiolvassa az elem értékét a verem tetejéről (ha van ilyen):
def peek(self): if not self.top: raise Exception("Stack is empty") return self.top.data
Jegyzet: Mindkettő interfésze Stack
osztályok ugyanaz – az egyetlen különbség az osztály metódusainak belső megvalósítása. Ez azt jelenti, hogy könnyedén válthat a különböző megvalósítások között, anélkül, hogy aggódnia kellene az osztályok belső elemei miatt.
A tömbök és a csatolt listák közötti választás az alkalmazás speciális követelményeitől és korlátaitól függ.
Verem megvalósítása a Python beépített struktúráival
Sok fejlesztő számára a verem felépítése a semmiből, bár oktatási célú, nem biztos, hogy a leghatékonyabb módja a verem használatának valós alkalmazásokban. Szerencsére sok népszerű programozási nyelv beépített adatstruktúrákkal és osztályokkal rendelkezik, amelyek természetesen támogatják a veremműveleteket. Ebben a részben megvizsgáljuk a Python e tekintetben kínált ajánlatait.
A Python sokoldalú és dinamikus nyelvként nem rendelkezik külön veremosztályokkal. Azonban a beépített adatstruktúrák, különösen a listák és a deque osztály a collections
modul, könnyedén stackként szolgálhat.
Python listák használata veremként
A Python listák dinamikus természetüknek és az olyan módszereknek köszönhetően, mint pl append()
és a pop()
.
-
Push művelet – Egy elem hozzáadása a verem tetejéhez olyan egyszerű, mint a
append()
eljárás:stack = [] stack.append('A') stack.append('B')
-
Pop művelet – A legfelső elem eltávolítása a
pop()
módszer minden érv nélkül:top_element = stack.pop()
-
Peek művelet A tetejére ugrás nélküli hozzáférést negatív indexeléssel lehet elérni:
top_element = stack[-1]
<p></p> miről Osztály tól gyűjtemény Modulok
A deque
(a double-ended queue rövidítése) osztály egy másik sokoldalú eszköz a verem-megvalósításokhoz. Mindkét végéről gyors hozzáfűzésekre és popupokra optimalizálták, így kissé hatékonyabb a veremműveletekhez, mint a listákhoz.
-
Inicializálás:
from collections import deque stack = deque()
-
Push művelet - Hasonlóan a listákhoz,
append()
módszert használják:stack.append('A') stack.append('B')
-
Pop művelet - Mint a listák,
pop()
módszer elvégzi a feladatot:top_element = stack.pop()
-
Peek művelet – A megközelítés ugyanaz, mint a listáknál:
top_element = stack[-1]
Mikor melyiket használjuk?
Míg a listák és a deque-ek egyaránt használhatók veremként, ha a struktúrát elsősorban veremként használja (egyik végéről hozzáfűzések és felugró elemek), a deque
optimalizálása miatt valamivel gyorsabb lehet. A legtöbb gyakorlati célra azonban, hacsak nem teljesítménykritikus alkalmazásokról van szó, a Python listái elegendőek.
Jegyzet: Ez a rész a Python beépített ajánlataival foglalkozik a veremszerű viselkedés érdekében. Nem feltétlenül kell újra feltalálnia a kereket (a stack a semmiből való megvalósításával), ha ilyen hatékony eszközök vannak a keze ügyében.
Potenciális halmozással kapcsolatos problémák és megoldásuk
Bár a veremek hihetetlenül sokoldalúak és hatékonyak, mint bármely más adatstruktúra, nem mentesek a potenciális buktatóktól. Alapvető fontosságú, hogy felismerjük ezeket a kihívásokat, amikor veremekkel dolgozik, és stratégiákat dolgozunk ki a megoldásukra. Ebben a részben belemerülünk néhány gyakori veremmel kapcsolatos problémába, és megvizsgáljuk a megoldásuk módjait.
kötegtúlcsordulást
Ez akkor fordul elő, amikor egy elemet megpróbálnak egy olyan verembe tolni, amely elérte a maximális kapacitását. Ez különösen olyan környezetekben jelent problémát, ahol a verem mérete rögzített, például bizonyos alacsony szintű programozási forgatókönyveknél vagy rekurzív függvényhívásoknál.
Ha tömb alapú veremeket használ, fontolja meg a dinamikus tömbök vagy a linkelt listák megvalósítására való váltást, amelyek átméretezik magukat. A verem túlcsordulás megelőzésének másik lépése a verem méretének folyamatos figyelése, különösen a leküldési műveletek előtt, és egyértelmű hibaüzenetek vagy figyelmeztetések a verem túlcsordulása esetén.
Ha a verem túlcsordulása a túlzott rekurzív hívások miatt következik be, fontolja meg az iteratív megoldásokat, vagy növelje a rekurziós korlátot, ha a környezet lehetővé teszi.
Stack Underflow
Ez akkor fordul elő, amikor egy üres veremből próbálnak kidobni egy elemet. Ennek elkerülése érdekében mindig ellenőrizze, hogy a verem üres-e, mielőtt pop- vagy peek-műveleteket hajtana végre. Egyértelmű hibaüzenet küldése, vagy kecsesen kezelje az alulcsordulást a program összeomlása nélkül.
Olyan környezetben, ahol ez elfogadható, fontolja meg egy speciális érték visszaadását, amikor üres veremből ugrik ki, jelezve a művelet érvénytelenségét.
Memória korlátok
Memóriakorlátos környezetben még a veremek dinamikus átméretezése is (például a csatolt listákon alapulóak) a memória kimerüléséhez vezethet, ha túl nagyra nőnek. Ezért tartsa szemmel az alkalmazás általános memóriahasználatát és a verem növekedését. Esetleg vezessen be egy puha sapkát a köteg méretére.
Szálbiztonsági aggályok
Többszálú környezetekben a megosztott verem különböző szálak általi egyidejű műveletei adatok inkonzisztenciájához vagy váratlan viselkedéshez vezethetnek. A probléma lehetséges megoldásai a következők lehetnek:
- Mutexek és zárak – Használjon mutexet (kölcsönös kizárási objektumokat) vagy zárakat annak biztosítására, hogy egy adott időpontban csak egy szál végezhessen műveleteket a veremen.
- Atomműveletek – Használja ki az atomi műveleteket, ha a környezet támogatja, hogy biztosítsa az adatok konzisztenciáját a push és pop műveletek során.
- Thread-local Stacks – Olyan esetekben, amikor minden szálnak szüksége van a saját veremére, fontolja meg a szálhelyi tároló használatát, hogy minden szálnak külön verempéldányt adjon.
Noha a veremek valóban nagy teljesítményűek, a lehetséges problémák tudatában és a megoldások aktív megvalósításában robusztus és hibamentes alkalmazások garantálhatók. Ezeknek a buktatóknak a felismerése a csata fele – a másik fele pedig a legjobb gyakorlatok átvétele a hatékony megoldásuk érdekében.
Következtetés
A veremek, látszólag egyszerű természetük ellenére, számos alapvető művelet alapját képezik a számítástechnika világában. Az összetett matematikai kifejezések elemzésétől a függvényhívások kezeléséig hasznosságuk széles és elengedhetetlen. Ahogy végigjártuk ennek az adatszerkezetnek a csínját-bínját, egyértelmű, hogy az erőssége nemcsak a hatékonyságában, hanem a sokoldalúságában is rejlik.
Azonban, mint minden eszköz esetében, a hatékonysága a használat módjától függ. Csak győződjön meg arról, hogy alaposan ismeri annak alapelveit, lehetséges buktatóit és bevált gyakorlatait, hogy ki tudja használni a veremek valódi erejét. Akár a semmiből valósítja meg az egyiket, akár a Pythonhoz hasonló nyelvek beépített szolgáltatásait használja, ezeknek az adatstruktúráknak a tudatos alkalmazása fogja kiemelni a megoldásait.
- SEO által támogatott tartalom és PR terjesztés. Erősödjön még ma.
- PlatoData.Network Vertical Generative Ai. Erősítse meg magát. Hozzáférés itt.
- PlatoAiStream. Web3 Intelligence. Felerősített tudás. Hozzáférés itt.
- PlatoESG. Carbon, CleanTech, Energia, Környezet, Nap, Hulladékgazdálkodás. Hozzáférés itt.
- PlatoHealth. Biotechnológiai és klinikai vizsgálatok intelligencia. Hozzáférés itt.
- Forrás: https://stackabuse.com/guide-to-stacks-in-python/
- :van
- :is
- :nem
- :ahol
- $ UP
- 1
- 14
- 20
- 7
- 8
- 9
- a
- Rólunk
- elfogadható
- Hozzáférés
- Eszerint
- elért
- aktívan
- tényleges
- tulajdonképpen
- hozzá
- hozzáadott
- hozzáadásával
- További
- cím
- Hozzáteszi
- Elfogadása
- Éber
- Minden termék
- kioszt
- lehetővé
- már
- Is
- mindig
- an
- és a
- Másik
- bármilyen
- külön
- Alkalmazás
- alkalmazások
- megközelítés
- VANNAK
- területek
- érv
- körül
- Sor
- fegyverraktár
- cikkben
- AS
- At
- kísérlet
- megkísérlése
- tudatában van
- alapján
- alapvető
- Csata
- BE
- mert
- előtt
- viselkedés
- viselkedés
- mögött
- hogy
- előnyös
- haszon
- BEST
- legjobb gyakorlatok
- között
- határ
- mindkét
- széles
- böngésző
- Épület
- beépített
- de
- by
- kéri
- TUD
- sapka
- Kapacitás
- eset
- esetek
- Okoz
- bizonyos
- kihívások
- Változások
- jellegzetes
- ellenőrizze
- Ellenőrzések
- választás
- osztály
- osztályok
- világos
- kód
- gyűjtemény
- kombinált
- hogyan
- Közös
- képest
- bonyolult
- bonyolultság
- számítási
- számítástechnika
- koncepció
- fogalmak
- következtetés
- Fontolja
- korlátok
- tartalmaz
- tartalmazott
- folyamatosan
- Mag
- drága
- Összeomlik
- teremt
- készítette
- kritikus
- Jelenlegi
- Jelenleg
- dátum
- Adatszerkezet
- foglalkozó
- elszánt
- mély
- mély merülést
- meghatározott
- meghatározott
- ás
- függ
- tervezett
- kívánatos
- Ellenére
- Fejlesztő
- fejlesztők
- különbség
- különböző
- tárgyalt
- merülés
- búvárkodás
- nem
- nem
- domain
- Don
- csinált
- hátránya
- két
- alatt
- dinamikus
- dinamikusan
- minden
- könnyen
- nevelési
- hatékonyan
- hatékonyság
- hatékonyság
- hatékony
- erőfeszítés nélkül
- elem
- elemek
- végén
- vége
- biztosítására
- biztosítása
- belép
- belép
- Környezet
- környezetek
- felszerelt
- hiba
- különösen
- lényeg
- alapvető
- Még
- Minden
- nyilvánvaló
- példa
- kivétel
- végrehajtó
- várható
- Magyarázza
- feltárása
- kifejezések
- szem
- berendezések
- GYORS
- gyorsabb
- Kedvenc
- ujjhegyek
- vezetéknév
- rögzített
- Összpontosít
- következik
- A
- szerencsére
- Előre
- talált
- ból ből
- Tele
- funkció
- funkcionalitás
- alapvető
- kap
- szerzés
- megy
- Ad
- adott
- Goes
- biztosít
- Nő
- Növekedés
- útmutató
- fél
- kéz
- fogantyú
- hands-on
- Esemény
- megtörténik
- hám
- Legyen
- fej
- segít
- lebeg
- Hogyan
- How To
- azonban
- HTTPS
- ICON
- if
- kép
- végre
- végrehajtás
- megvalósítások
- végrehajtási
- munkagépek
- in
- beleértve
- következetlenségek
- Növelje
- hihetetlenül
- valóban
- index
- példa
- Felület
- belső
- bele
- belső
- bevezet
- Bevezetés
- intuitív
- kérdés
- kérdések
- IT
- ITS
- maga
- Munka
- éppen
- Tart
- ismert
- nyelv
- Nyelvek
- nagy
- keresztnév
- vezet
- tanulás
- Szabadság
- balra
- hadd
- Tőkeáttétel
- erőfölény
- LG
- fekszik
- fény
- mint
- LIMIT
- összekapcsolt
- Lista
- listák
- kis
- ll
- Zárak
- néz
- készült
- csinál
- KÉSZÍT
- Gyártás
- vezetés
- kezelése
- sok
- matematikai
- maximális
- Lehet..
- jelenti
- eszközök
- Memory design
- üzenet
- üzenetek
- módszer
- mód
- esetleg
- Modulok
- monitor
- ellenőrizni
- több
- hatékonyabb
- a legtöbb
- mozog
- menj tovább
- sok
- többszörös
- kölcsönös
- Természet
- szükségszerűen
- Szükség
- szükséges
- igények
- negatív
- Új
- következő
- nem
- csomópont
- Most
- árnyalatok
- objektumok
- megállapítja,
- of
- ajánlat
- Ajánlat
- on
- egyszer
- ONE
- csak
- -ra
- működés
- Művelet
- optimalizálás
- optimalizált
- or
- Más
- Egyéb
- másképp
- mi
- ki
- felett
- átfogó
- Overcome
- paraméter
- különösen
- Emberek (People)
- Teljesít
- talán
- engedélyek
- person
- Hely
- forgalomba
- Plató
- Platón adatintelligencia
- PlatoData
- rengeteg
- pont
- pont
- pop
- Pops
- Népszerű
- rendelkezik
- potenciális
- hatalom
- erős
- Gyakorlati
- gyakorlat
- jelenlét
- megakadályozása
- Megelőzés
- előző
- korábban
- elsősorban
- elsődleges
- alapelv
- elvek
- Probléma
- problémák
- Program
- Programozás
- programozási nyelvek
- ad
- célokra
- Nyomja
- Piton
- egészen
- emel
- hatótávolság
- RE
- elérte
- való Világ
- elismerik
- felismerés
- rekurzív
- csökkenteni
- referencia
- tekintik
- feltalálni
- figyelemre méltó
- eltávolítása
- képvisel
- szükség
- követelmények
- eredményez
- visszatérés
- visszatérő
- Visszatér
- Gyűrű
- erős
- Tekercs
- s
- Biztonság
- azonos
- forgatókönyvek
- kaparni
- Rész
- lát
- látszólag
- MAGA
- különálló
- Series of
- szolgál
- készlet
- árnyék
- megosztott
- adatlap
- rövid
- kellene
- oldal
- jelentőség
- jelent
- hasonló
- Egyszerű
- egyszerűség
- egyszerűen
- óta
- egyetlen
- Méret
- Puha
- Megoldások
- néhány
- Hely
- speciális
- specializált
- különleges
- verem
- Stackabus
- Stacks
- szabványok
- kezdet
- Állami
- Lépés
- megáll
- tárolás
- memorizált
- árnyékolók
- egyértelmű
- stratégiák
- erő
- struktúra
- struktúrák
- ilyen
- támogatás
- Támogatott
- Támogatja
- biztos
- környező
- SVG
- SWIFT
- kapcsoló
- Vesz
- tart
- mint
- hogy
- A
- azok
- Őket
- maguk
- akkor
- Ott.
- ebből adódóan
- Ezek
- ők
- dolog
- dolgok
- Szerintem
- ezt
- azok
- három
- Keresztül
- idő
- nak nek
- is
- szerszám
- szerszámok
- felső
- legmagasabb
- hagyományos
- átmenet
- fordít
- igaz
- megpróbál
- próbál
- kettő
- alátámasztani
- megértés
- Váratlan
- Használat
- használ
- használt
- segítségével
- hasznosság
- érték
- Értékek
- változó
- Hatalmas
- Ve
- sokoldalú
- sokoldalúság
- fontos
- akar
- Út..
- módon
- we
- háló
- webböngésző
- Mit
- Mi
- Kerék
- amikor
- vajon
- ami
- míg
- WHO
- miért
- széles
- Széleskörű
- lesz
- val vel
- belül
- nélkül
- Munka
- dolgozó
- világ
- aggódik
- betakar
- év
- még
- te
- A te
- zephyrnet