Mkusanyiko wa data. Muundo wa data: dhana ya jumla, utekelezaji. Miundo rahisi zaidi ya data: foleni, safu. Kwa kutumia rundo na nukuu ya Kipolandi kinyume. Kutumia stack katika programu

wa mwisho ndani - wa kwanza kutoka, "wa mwisho ndani - wa kwanza kutoka").

Mara nyingi, kanuni ya uendeshaji wa stack inalinganishwa na safu ya sahani: kuchukua ya pili kutoka juu, unahitaji kuondoa moja ya juu.

Katika lugha zingine (kwa mfano, Lisp, Python), orodha yoyote inaweza kuitwa safu, kwani shughuli za pop na kushinikiza zinapatikana kwao. Katika C ++, maktaba ya kawaida ina darasa na muundo na mbinu zilizotekelezwa. Na kadhalika.

Encyclopedic YouTube

    1 / 3

    Sayansi ya kompyuta. Miundo ya data: Stack. Kituo cha Mafunzo ya Mtandaoni cha Foxford

    #9. Stack / 1. Assembler na taratibu / Programming kutoka mwanzo

    Misingi ya mitandao ya data. Mfano wa OSI na stack Itifaki za TCP IP. Misingi ya Ethernet.

    Manukuu

Rafu ya programu

Shirika katika kumbukumbu

Mara nyingi, safu hutekelezwa kama orodha ya njia moja (kila kipengele kwenye orodha kina, pamoja na taarifa iliyohifadhiwa kwenye rafu, kielekezi kwa kipengele kinachofuata cha rafu).

Lakini stack pia mara nyingi iko katika safu moja-dimensional na anwani zilizoagizwa. Shirika hili la stack ni rahisi ikiwa kipengele cha habari kinachukua kumbukumbu kiasi fasta maneno, kwa mfano, neno 1. Hili huondoa hitaji la kuhifadhi kiashirio dhahiri kwa kipengele kifuatacho cha rafu katika kipengee cha rafu, ambacho huhifadhi kumbukumbu. Katika kesi hii, kiashiria cha stack ( Kielekezi cha Stack, - SP) ni kawaida rejista ya processor na inaelekeza kwa anwani ya kichwa cha stack.

Kwa mfano, tuseme kwamba kichwa cha stack iko kwenye anwani ya chini, vipengele vifuatavyo viko kwenye anwani zinazoongezeka. Kila neno linaposukumwa kwenye rafu, SP kwanza hupunguzwa kwa 1 na kisha anwani kutoka SP inaandikwa kwenye kumbukumbu. Kila wakati neno linapotolewa kutoka kwa rafu, kwanza husoma anwani ya sasa kutoka SP na kisha huongeza yaliyomo kwenye SP kwa 1.

Wakati wa kupanga safu kama orodha ya unidirectional, thamani ya tofauti ya rafu ni kiashirio kuelekea juu yake - anwani ya sehemu ya juu. Ikiwa safu ni tupu, basi thamani ya pointer ni NULL.

Mfano wa utekelezaji wa stack katika C:

struct stack (char * data; struct stack * inayofuata; );

Uendeshaji wa Stack

Kuna shughuli tatu zinazowezekana kwenye stack: kuongeza kipengele (aka kusukuma), kuondoa kipengele (pop) na kusoma kipengele cha kichwa (peek).

Wakati wa kusukuma (kusukuma) kipengele kipya kinaongezwa, akielezea kipengele ambacho hapo awali kilikuwa kichwa. Kipengele kipya sasa inakuwa kichwa.

Wakati wa kufuta kipengele (pop), cha kwanza kinaondolewa, na kichwa kinakuwa kile ambacho kitu hiki kilikuwa na pointer (kipengele kinachofuata). Katika kesi hii, thamani ya kipengele kilichoondolewa inarejeshwa.

msukuma utupu (STACK * ps, int x) // Kuongeza kipengee kipya kwenye safu( ikiwa ( ps -> size == STACKSIZE ) // Je, stack inafurika?( fputs ( "Hitilafu: kufurika kwa rafu \n " , stderr ); ondoa (); ) vinginevyo ( ps -> vitu [ ps -> size ++ ] = x ; ) ) int pop ( STACK * ps ) // Ondoa kwenye stack( ikiwa ( ps -> size == 0 ) // Je, rundo tupu?( fputs ( "Error: stack underflow \n " , stderr ); acha (); ) vinginevyo ( rudisha ps -> vitu [ -- ps -> size ]; ) )

Eneo la maombi

Mwonekano wa upangaji wa rafu hutumika kupitisha miundo ya data, kama vile mti au grafu. Kutumia kazi za kujirudia Stack pia itatumika, lakini aina yake ya vifaa. Mbali na madhumuni haya, stack hutumiwa kuandaa

Michakato sawa hutokea wakati wa kukatizwa kwa maunzi (X86 processor with usumbufu wa vifaa huhifadhi kiotomatiki rejista ya bendera kwenye rafu). Kwa kuongezea, wakusanyaji huweka utaratibu wa viambajengo vya ndani kwenye rafu (ikiwa kichakataji kinaweza kufikia eneo la mrundikano wa nasibu).

Kabla ya rafu kutumika, lazima ianzishwe ili rejista za SS:ESP zielekeze kwenye anwani ya kichwa cha rafu katika eneo halisi. kumbukumbu ya ufikiaji bila mpangilio, na kwa ajili ya kuhifadhi data katika stack ni muhimu kuhifadhi idadi inayotakiwa ya seli za kumbukumbu (kwa wazi, stack katika ROM, kwa kawaida, haiwezi kupangwa). Programu za maombi, kama sheria, kutoka mfumo wa uendeshaji pokea mrundikano ulio tayari kuliwa. Katika hali ya kichakataji iliyolindwa, sehemu ya hali ya kazi ina viteuzi vinne vya rafu (kwa viwango tofauti marupurupu), lakini fungu moja tu hutumiwa kwa wakati mmoja.

Stack ni jambo la programu na suluhisho la asili. Stack mara moja ilikuja kwenye biashara ya kompyuta na ikawa "asili", kana kwamba ndipo yote yalipoanzia.

Bila stack, processor haifanyi kazi, hakuna kujirudia, na haiwezekani kuandaa simu za kazi za ufanisi. Algorithm yoyote inaweza kufanya bila foleni, orodha, mkusanyiko, safu, au mfumo wa vitu vilivyopangwa, lakini hakuna kitu kinachofanya kazi bila kumbukumbu na stack, ikiwa ni pamoja na yote yaliyo hapo juu.

Mwanzoni mwa mwanzo: processor, kumbukumbu na stack

Kumbukumbu bora hutoa kushughulikia moja kwa moja kwa thamani - hizi ni viwango vya mashine na lugha shahada ya juu. Katika kesi ya kwanza, processor inarudia kwa mtiririko kupitia anwani za kumbukumbu na kutekeleza maagizo. Katika kesi ya pili, programu huendesha safu. Vipindi vyote viwili vina:

  • anwani = thamani;
  • index = thamani.

Anwani inaweza kuwa kamili na jamaa, index inaweza kuwa digital na associative. Anwani na faharasa zinaweza kuwa na anwani nyingine zaidi ya thamani, lakini haya ni maelezo ya anwani isiyo ya moja kwa moja. Bila kumbukumbu, processor haiwezi kufanya kazi, na bila safu ya amri na data, ni kama mashua bila makasia.

Mlundikano wa sahani ni hadithi ya kitamaduni kuhusu kiini cha mrundikano: dhana ya mrundikano na tafsiri katika ufahamu wa kawaida. Huwezi kuchukua sahani kutoka chini, unaweza kuichukua tu kutoka juu, na kisha sahani zote zitakuwa sawa.

Chochote kinachokuja mwisho kwenye safu huenda kwanza. Suluhisho kamili. Kwa asili, stack, kama tafsiri ya hatua moja hadi nyingine, inabadilisha wazo la algorithm kama mlolongo wa shughuli.

Kiini na dhana ya stack

Kichakataji na kumbukumbu ndio nyenzo kuu za ujenzi wa kompyuta. Kichakataji hutekeleza maagizo, huchezea anwani za kumbukumbu, na kurejesha na kurekebisha maadili kwenye anwani hizi. Katika lugha ya programu, yote haya yanabadilishwa kuwa vigezo na maadili yao. Kiini cha safu na dhana ya mwisho katika wa kwanza kutoka (LIFO) bado haijabadilika.

Kifupi LIFO haitumiki tena mara nyingi kama ilivyokuwa. Labda kwa sababu orodha zimebadilishwa kuwa vitu, na kwanza kwenye foleni za kwanza (FIFO) hutumiwa kama inahitajika. Mienendo ya aina za data imepoteza umuhimu wake katika muktadha wa kuelezea vigezo, lakini imepata umuhimu wake wakati wa utekelezaji wa misemo: aina ya data imedhamiriwa wakati wa matumizi yake, na hadi wakati huo unaweza kuelezea. chochote na kwa njia yoyote unayotaka.

Kwa hivyo, stack - ni nini? Sasa unajua kwamba hili ni swali lisilofaa. Baada ya yote, bila stack hakuna programu za kisasa. Simu yoyote ya kukokotoa inamaanisha kupitisha vigezo na anwani ya kurudi. Kazi inaweza kuita kazi nyingine - hii ni tena kupita vigezo na anwani ya kurudi. Kuweka utaratibu wa kupiga simu bila rundo ni kazi ya ziada, ingawa suluhisho linalowezekana hakika linawezekana.

Watu wengi huuliza: "Stack - ni nini?" Katika muktadha wa simu ya kukokotoa, ina vitendo vitatu:

  • kuokoa anwani ya kurudi;
  • kuokoa vigezo vyote vilivyohamishwa au anwani kwao;
  • simu ya kazi.

Mara tu kazi inayoitwa imekamilisha utume wake, itarudi tu udhibiti kwenye anwani ya kurudi. Chaguo za kukokotoa zinaweza kuita idadi yoyote ya vitendaji vingine, kwani kikomo ni saizi ya rafu pekee.

Tabia za stack

Rafu sio aina ya data dhahania, lakini utaratibu halisi. Katika kiwango cha processor, ni "injini" ambayo husafisha na kukamilisha kazi ya mzunguko mkuu wa processor. Kama hesabu kidogo, rundo hunasa sheria rahisi na dhahiri za utendakazi. Ni ya kuaminika na salama.

Tabia ya sifa ya stack ni ukubwa wake na urefu wa vipengele vyake. Katika kiwango cha processor, kila kitu kinatambuliwa na uwezo kidogo, anwani ya kumbukumbu na fizikia ya kuipata. Kipengele cha kuvutia na mila: stack inakua chini, yaani, kuelekea kupungua kwa anwani za kumbukumbu, na kumbukumbu ya programu na data - juu. Hii ni ya kawaida, lakini haihitajiki. Maana hapa ni muhimu - alikuja mwisho na kushoto kwanza. Sheria hii rahisi ya kushangaza hukuruhusu kuunda algoriti za kupendeza zinazofanya kazi katika lugha ngazi ya juu. Sasa hautauliza, stack ni nini?

Kazi isiyofaa vifaa imekuwa kawaida kwa muda mrefu sana, lakini katika mstari wa mbele teknolojia ya habari Wazo la stack ni kupata programu mpya na za kuahidi.

Kimsingi, haijalishi stack iko kwenye kiwango cha processor. Ni sehemu ya asili ya usanifu wa kompyuta. Lakini katika programu, stack inategemea maombi maalum na uwezo wa programu.

Mkusanyiko, mikusanyiko, orodha, foleni... Rafu!

Mara nyingi watu huuliza swali: "Stack - ni nini?" "Programu" na "utaratibu" ni dhana zinazovutia: sio visawe, lakini zinahusiana sana. Upangaji programu umeenda kwa haraka sana hivi kwamba kilele kilichofikiwa kinaonekana kuwa bora. Uwezekano mkubwa zaidi hii sivyo. Lakini ni wazi kitu kingine.

Wazo la stack limejulikana sio tu katika kiwango cha lugha mbalimbali za programu, lakini pia katika kiwango cha miundo na uwezo wao wa kuunda aina za data. Safu yoyote ina kushinikiza na pop, na dhana ya "mambo ya kwanza na ya mwisho ya safu" yamekuwa ya jadi. Hapo awali kulikuwa na vitu vya safu tu, lakini leo kuna:

  • vipengele vya safu;
  • kipengele cha kwanza cha safu;
  • kipengele cha mwisho cha safu.

Uendeshaji wa kuweka kipengele katika safu husonga pointer, na kurejesha kipengele kutoka mwanzo wa safu au kutoka mwisho wake hufanya tofauti. Kimsingi hii ni safu sawa, lakini inatumika kwa aina zingine za data.

Ni vyema ijulikane kwamba lugha maarufu programu hazina muundo wa safu. Lakini wanatoa wazo lake kwa msanidi programu kwa ukamilifu.

Rafu ni mkusanyiko ambao vipengee vyake hupatikana kwa msingi wa kuingia, wa kwanza. (Mwisho-Katika-Kwanza-Kutoka au LIFO). Hii ina maana kwamba tutaweza tu kufikia kipengele cha mwisho kilichoongezwa.

Tofauti na orodha, hatuwezi kufikia kipengele kiholela cha rafu. Tunaweza tu kuongeza au kuondoa vipengele kwa kutumia mbinu maalum. Rafu pia hazina njia Ina kama orodha zinavyofanya. Pia, rafu haina kiboreshaji. Ili kuelewa kwa nini vikwazo vile vimewekwa kwenye stack, hebu tuangalie jinsi inavyofanya kazi na jinsi inavyotumiwa.

Mfano wa kawaida wa kuelezea stack ni safu ya sahani. Bila kujali ni sahani ngapi kwenye rafu, tunaweza kuondoa ya juu kila wakati. Sahani safi zimewekwa juu ya stack kwa njia ile ile, na tutachukua daima sahani ambayo iliwekwa mwisho kwanza.

Ikiwa tunaweka, kwa mfano, sahani nyekundu, kisha bluu, na kisha kijani, basi kwanza tutahitaji kuondoa kijani, kisha bluu, na hatimaye nyekundu. Jambo kuu la kukumbuka ni kwamba sahani zimewekwa daima juu ya stack. Wakati mtu anachukua sahani, pia huiondoa kutoka juu. Inatokea kwamba sahani zinavunjwa kwa utaratibu kinyume na moja ambayo ziliwekwa.

Sasa kwa kuwa tunaelewa jinsi stack inavyofanya kazi, hebu tuanzishe maneno machache. Uendeshaji wa kuongeza kipengele kwenye stack inaitwa "kushinikiza", na kuiondoa inaitwa "pop". Kipengele cha mwisho kilichoongezwa kinaitwa sehemu ya juu ya rafu, au "juu", na inaweza kutazamwa kwa kutumia operesheni ya "peek". Wacha sasa tuangalie kiolezo cha darasa kinachotumia safu.

Darasa la stack

Darasa la Stack hufafanua mbinu za Kushinikiza, Pop, Peek za kufikia vipengele, na sehemu ya Hesabu. Katika utekelezaji tutatumia LinkedList kwa kuhifadhi vitu.

Rafu ya darasa la umma (List _items = Orodha Mpya Iliyounganishwa(); Push batili ya umma (thamani ya T) (  tupa NotImplementedException (); ) T Pop mpya ya umma () ( tupa NotImplementedException mpya (); ) T Peek ya umma () ( tupa mpya NotImplementedException();) Hesabu ya int ya umma ( pata; ) )

Mbinu ya kusukuma

  • Tabia: Huongeza kipengele juu ya rafu.
  • Utata: O(1).

Kwa kuwa tunatumia orodha iliyounganishwa kwenye vipengee vya hifadhi, tunaweza tu kuongeza mpya hadi mwisho wa orodha.

Push utupu wa umma(thamani ya T) ( _items.AddLast(thamani);)

Mbinu ya pop

  • Tabia: Huondoa kipengele kutoka juu ya rafu na kukirejesha. Ikiwa rafu haina kitu, tupa InvalidOperationException.
  • Utata: O(1).

Push huongeza vipengele hadi mwisho wa orodha, hivyo itawachukua pia kutoka mwisho. Ikiwa orodha ni tupu, ubaguzi utatupwa.

T Pop() ya Umma () ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("Rundo ni tupu"); ) T tokeo = _items.Tail.Value; _items.RemoveLast(); rejesha matokeo; )

Mbinu ya kutazama

  • Tabia: Inarudi kipengele cha juu stack, lakini haifuti. Ikiwa rafu haina kitu, tupa InvalidOperationException.
  • Utata: O(1).
public T Peek() ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("Rundo ni tupu"); ) rudisha _items.Tail.Value; )

Mbinu ya kuhesabu

  • Tabia: Hurejesha idadi ya vipengele kwenye rafu.
  • Utata: O(1).

Kwa nini tunahitaji kujua ni vipengele vingapi vilivyo kwenye rafu ikiwa hata hivyo hatuwezi kuvifikia? Kwa uga huu tunaweza kuangalia kama kuna vipengele kwenye rafu au ikiwa ni tupu. Hii ni muhimu sana kwa kuzingatia hilo Mbinu ya pop hutupa ubaguzi.

Mfano: kikokotoo katika nukuu ya Kipolandi kinyume.

Mfano wa kawaida wa kutumia rafu ni kikokotoo katika nukuu ya Kipolandi kinyume, au postfix. Ndani yake imeandikwa operator baada ya shughuli zao. Hiyo ni, tunaandika:

<операнд> <операнд> <оператор>

badala ya ile ya jadi:

<операнд> <оператор> <операнд>

Kwa maneno mengine, badala ya "4 + 2" tutaandika "4 2 +". Ikiwa una nia ya asili ya nukuu ya Kipolandi iliyo kinyume na jina lake, unaweza kujua kuihusu kwenye Wikipedia au katika injini ya utafutaji.

Jinsi nukuu ya Kipolandi inavyokokotolewa na kwa nini rafu ni muhimu sana unapoitumia inaweza kuonekana wazi kutoka kwa algoriti ifuatayo:

Kwa kila thamani ya ingizo ikiwa thamani ni nambari kamili, sukuma thamani kwenye rafu ya uendeshaji vinginevyo ikiwa thamani ni opereta toa thamani za kushoto na kulia kutoka kwenye rafu, tathmini opereta asukuma tokeo kwenye jibu la rafu kutoka kwa rafu. .

Hiyo ni, kwa usemi "4 2 +" vitendo vitakuwa kama ifuatavyo:

Shinikiza (4) sukuma(2) sukuma(pop() + pop())

Mwishoni kutakuwa na thamani moja kwenye stack - 6.

Ifuatayo ni kanuni kamili calculator rahisi, ambayo husoma usemi (kwa mfano, 4 2 +) kutoka kwa kiweko, hugawanya ingizo kwa nafasi (["4", "2", "+"]) na kutekeleza algorithm ya hesabu. Tathmini inaendelea hadi neno kuacha lipatikane.

Utupu RpnLoop() ( wakati (kweli) ( Console.Write("> "); ingizo la kamba = Console.ReadLine(); ikiwa (input.Trim().ToLower() == "quit") ( break; ) / / Rundo la thamani ambazo bado hazijachakatwa = Thamani za Rafu = Stack mpya(); foreach (tokeni ya mfuatano katika ingizo. Gawanya(char mpya ( " " ))) ( // Ikiwa thamani ni nambari kamili... thamani ya int; ikiwa (int. TryParse(ishara, thamani ya nje)) ( // ... weka kwenye rafu. values.Push(value); ) vinginevyo ( // vinginevyo fanya operesheni... int rhs = values .Pop(); int lhs = values.Pop(); // ... na urudishe matokeo. badilisha (tokeni) ( kipochi "+": values.Push(lhs + rhs); break; herufi "-" : values.Push(lhs - rhs ); break; case "*": values.Push(lhs * rhs); break; case "/": values.Push(lhs / rhs); break; kesi "%": maadili .Push(lhs % rhs); vunja; chaguo-msingi: // Ikiwa utendakazi si +, -, * au / kutupa mpya ArgumentException(string.Format("Tokeni isiyotambulika: (0)", tokeni)); ) ) ) // Kipengele cha mwisho kwenye rafu ni matokeo Console.WriteLine(values.Pop()); ))

Foleni

Foleni zinafanana sana na rafu. Pia haitoi ufikiaji wa kipengee cha kiholela, lakini, tofauti na stack, vipengele vimewekwa (msururu) na kupanda (mlolongo) kutoka ncha tofauti. Njia hii inaitwa "kwanza ndani, kwanza kutoka" (Kwanza-Kwa-Kwanza-Kutoka au FIFO). Hiyo ni, tutachukua vipengele kutoka kwenye foleni kwa utaratibu sawa kama tunavyoweka. Kama foleni halisi au conveyor.

Foleni mara nyingi hutumika katika programu ili kutoa bafa ambamo vipengee vinaweza kuwekwa kwa ajili ya kuchakatwa baadaye huku vikihifadhi mpangilio ambavyo vinafika. Kwa mfano, ikiwa hifadhidata inasaidia muunganisho mmoja tu, unaweza kutumia foleni ya nyuzi ambazo, isiyo ya kawaida, zitasubiri zamu yao kufikia hifadhidata.

Darasa la foleni

Darasa la Foleni, kama mrundikano, litatekelezwa kwa kutumia orodha iliyounganishwa. Itatoa Enqueue kuongeza kipengele, Dequeue kuondoa, Peek na Hesabu mbinu. Kama darasa la Stack, haitatumia kiolesura cha ICollection , kwa kuwa haya ni makusanyo ya makusudi maalum.

Foleni ya darasa la umma (List LinkedList = new LinkedList(); Enqueue tupu ya umma(thamani ya T) (  tupa NotImplementedException (); ) T Dequeue ya umma() ( tupa NotImplementedException mpya (); ) T Peek ya umma () ( tupa mpya NotImplementedException();) Hesabu ya int ya umma ( pata; ) )

Mbinu ya mlolongo

  • Tabia: Huongeza kipengele kwenye foleni.
  • Utata: O(1).

Vipengele vipya vya foleni vinaweza kuongezwa ama mwanzoni mwa orodha au hadi mwisho. Ni muhimu tu kwamba vipengele vinafikiwa kutoka kwa makali kinyume. Katika utekelezaji huu, tutaongeza vipengele vipya kwa mwanzo wa orodha ya ndani.

Foleni ya utupu ya umma(thamani ya T) ( _items.OngezaKwanza(thamani);)

Mbinu ya kupanga foleni

  • Tabia: Huondoa kipengee kilichowekwa kwanza kwenye foleni na kukirejesha. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).

Kwa kuwa tunaingiza vipengele mwanzoni mwa orodha, tutawaondoa kutoka mwisho. Ikiwa orodha ni tupu, ubaguzi hutupwa.

Umma T Dequeue() ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("Foleni ni tupu"); ) T mwisho = _items.Tail.Value; _items.RemoveLast(); rudisha mwisho; )

Mbinu ya kutazama

  • Tabia: Hurejesha kipengele ambacho kitarejeshwa kwa simu inayofuata kwa mbinu ya Dequeue. Foleni bado haijabadilika. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).
public T Peek() ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("Foleni ni tupu"); ) rudisha _items.Tail.Value; )

Mbinu ya kuhesabu

  • Tabia:
  • Utata: O(1).
hesabu ya int ya umma ( pata ( rudisha _items.Count; ) )

Foleni ya njia mbili

Foleni ya njia mbili (Foleni iliyoisha mara mbili), au Des (Deque), huongeza tabia ya foleni. Katika deque, unaweza kuongeza au kuondoa vipengele kutoka mwanzo na mwisho wa foleni. Tabia hii ni muhimu katika kazi nyingi, kama vile kuratibu nyuzi au kutekeleza miundo mingine ya data. Baadaye tutaangalia kutekeleza stack kwa kutumia deque.

Dequer darasa

Darasa la Deque ni rahisi kutekeleza kwa kutumia orodha iliyounganishwa mara mbili. Inakuruhusu kutazama, kufuta na kuongeza vipengee mwanzo na mwisho wa orodha. Tofauti kuu kati ya foleni ya njia mbili na ya kawaida ni kwamba njia za Enqueue , Dequeue na Peek zimegawanywa katika jozi ili kufanya kazi kwenye ncha zote mbili za orodha.

Utaftaji wa tabaka la umma (List _items = Orodha Mpya Iliyounganishwa(); utupu wa umma EnqueueFirst(thamani ya T) ( tupa NotImplementedException mpya(); ) utupu wa umma EnqueueLast(thamani ya T) ( tupa NotImplementedException mpya(); ) T DequeueFirst ya umma( ) ( tupa NotImplementedException mpya (); ) T DequeueLast () tupa NotImplementedException mpya (); ) T PeekFirst () tupa NotImplementedException mpya (); ) T PeekLast () ya umma T PeekLast() ( tupa NotImplementedException mpya (); ) int ya umma Hesabu (pata;))

Njia ya EnqueueKwanza

  • Tabia:
  • Utata: O(1).
utupu wa umma EnqueueFirst(thamani ya T) ( _items.AddFirst(thamani);)

EnqueueMbinu ya mwisho

  • Tabia:
  • Utata: O(1).
utupu wa umma EnqueueLast(thamani ya T) ( _items.AddLast(thamani);)

Njia ya DequeueFirst

  • Tabia: Huondoa kipengele mbele ya foleni na kukirejesha. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).
public T DequeueFirst() ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("DequeueFirst called when deque is tupu"); ) T temp = _items.Head.Value; _items.RemoveFirst(); halijoto ya kurudi; )

Mbinu ya DequeueLast

  • Tabia:
  • Utata: O(1).
public T DequeueLast() ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("DequeueLast called when deque is tupu"); ) T temp = _items.Tail.Value; _items.RemoveLast(); halijoto ya kurudi; )

Mbinu ya PeekFirst

  • Tabia: Hurejesha kipengele kutoka mwanzo wa foleni bila kukirekebisha. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).
public T PeekFirst() ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("PeekFirst inaitwa wakati deque ni tupu"); ) rudisha _items.Head.Value; )

Mbinu ya PeekLast

  • Tabia:
  • Utata: O(1).
public T PeekLast() ( ikiwa (_items.Count == 0) ( tupa InvalidOperationException mpya("PeekLast inaitwa wakati deque ni tupu"); ) rudisha _items.Tail.Value; )

Mbinu ya kuhesabu

  • Tabia: Hurejesha idadi ya vipengele kwenye foleni, au 0 ikiwa foleni ni tupu.
  • Utata: O(1).
hesabu ya int ya umma ( pata ( rudisha _items.Count; ) )

Mfano: Utekelezaji wa Stack

Deque mara nyingi hutumiwa kutekeleza miundo mingine ya data. Hebu tuangalie mfano wa kutekeleza stack kutumia.

Huenda unashangaa kwa nini utekeleze mkusanyiko kulingana na foleni badala ya orodha iliyounganishwa. Kuna sababu mbili: utendaji na tumia tena kanuni. Orodha iliyounganishwa ina kichwa cha juu cha kuunda nodi na hakuna dhamana ya eneo la data: vitu vinaweza kupatikana mahali popote kwenye kumbukumbu, ambayo husababisha. idadi kubwa ya inakosa na uharibifu wa utendaji katika kiwango cha processor. Utekelezaji mzuri zaidi wa deque unahitaji safu ili kuhifadhi vipengee.

Walakini, kutekeleza safu au foleni kwa kutumia safu ni si kazi rahisi, lakini kutekeleza deque kwa njia hii na kuitumia kama msingi wa miundo mingine ya data kutatupatia manufaa makubwa ya utendakazi na kuturuhusu kutumia tena msimbo. Hii inapunguza gharama za usaidizi.

Tutaangalia lahaja ya foleni kwa kutumia safu baadaye, lakini kwanza hebu tuangalie darasa la mrundikano kwa kutumia mfuatano:

Rafu ya daraja la umma ( Deque _items = Deque mpya(); Push batili ya umma (thamani ya T) ( _items. EnqueueFirst(thamani); ) T Pop ya umma() ( rudisha _items.DequeueFirst(); ) T Peek ya umma() ( rudisha _items .PeekFirst(); ) Hesabu ya int ya umma ( pata ( rudisha _items.Count; ) ) )

Kumbuka kuwa ushughulikiaji wote wa makosa sasa unashughulikiwa na darasa la Deque, na kwa kuongeza, uboreshaji wowote wa foleni pia utaakisiwa kwenye rafu. Utekelezaji wa foleni ya kawaida ya kwenda na kurudi ni rahisi sana hivi kwamba tutaiacha kama zoezi kwa msomaji.

Kuhifadhi vipengele katika safu

Kama ilivyoelezwa tayari, kutekeleza foleni kwa kutumia safu kuna faida zake. Inaonekana rahisi, lakini kwa kweli kuna idadi ya nuances ambayo inahitaji kuzingatiwa.

Hebu tuangalie matatizo yanayoweza kutokea na jinsi ya kuyatatua. Kwa kuongeza, tutahitaji maelezo kuhusu kuongeza safu ya ndani kutoka kwa makala iliyotangulia juu ya safu zinazobadilika.

Wakati foleni imeundwa, safu ya urefu wa sifuri huundwa ndani yake. Herufi nyekundu "h" na "t" zinasimama kwa viashiria _kichwa na _mkia, mtawalia.

Deque deq = Deque mpya (); deq.EnqueueKwanza(1);

Deq.EnqueueLast(2);

Deq.EnqueueKwanza(0);

Tafadhali kumbuka: index ya "kichwa" cha foleni imeruka hadi mwanzo wa orodha. Sasa kipengele cha kwanza ambacho kitarejeshwa wakati wa kupiga njia ya DequeueFirst ni 0 (index 3).

Deq.EnqueueLast(3);

Safu imejaa, kwa hivyo wakati wa kuongeza kipengee ifuatayo itatokea:

  • Kanuni ya ukuaji itaamua ukubwa wa safu mpya.
  • Vipengele vitanakiliwa kwa safu mpya kutoka kichwa hadi mkia.
  • Kipengele kipya kitaongezwa.
deq.EnqueueLast(4);

Sasa hebu tuone nini kinatokea wakati kipengele kinapoondolewa:

Deq.DequeueFirst();

Deq.DequeueLast();

Wakati muhimu: bila kujali uwezo au ukamilifu wa safu ya ndani, kimantiki, yaliyomo ya foleni ni vipengele kutoka "kichwa" hadi "mkia", kwa kuzingatia "mviringo". Tabia hii pia inaitwa "bafa ya pete".

Sasa tuangalie utekelezaji.

Dequer darasa (kwa kutumia safu)

Usano wa foleni kulingana na safu ni sawa na katika kesi ya utekelezaji wa orodha iliyounganishwa. Hatutarudia. Walakini, kwa kuwa orodha ilibadilishwa na safu, tuliongeza uwanja mpya - safu yenyewe, saizi yake na viashiria kwa "mkia" na "kichwa" cha foleni.

Mpangilio wa darasa la umma ( T _items = T mpya; // Idadi ya vipengele katika foleni. int _size = 0; // Fahirisi ya kipengele cha kwanza (cha zamani zaidi). int _head = 0; // Fahirisi ya kipengele cha mwisho (mpya zaidi) int _tail = -1; ... )

Algorithm ya ukuaji

Lini mahali pa bure katika mwisho wa safu ya ndani, inahitaji kuongezeka, vipengele vinakiliwa na viashiria vya "mkia" na "kichwa" vinasasishwa. Operesheni hii inafanywa ikiwa ni lazima wakati wa kuongeza kipengele. Kigezo cha kuanziaIndex kinatumika kuonyesha ni sehemu ngapi zinafaa kuachwa wazi mwanzoni (ikiwa ni kuongeza mwanzo).

Angalia jinsi data inavyorejeshwa wakati unapaswa kuruka hadi mwanzo wa safu wakati wa kwenda kutoka kichwa hadi mkia.

Utupu wa kibinafsi kutengaNewArray(int startingIndex) ( int newLength = (_size == 0) ? 4: _size * 2; T newArray = T mpya; ikiwa (_size > 0) ( int targetIndex = startingIndex; // Nakili yaliyomo... / / Ikiwa safu haijafungwa, nakala tu vipengele. // Vinginevyo, nakala kutoka kichwa hadi mwisho, na kisha kutoka mwanzo wa safu hadi mkia. // Ikiwa mkia ni chini ya kichwa, nenda mwanzo. ikiwa (_mkia< _head) { // Копируем _items.._items в newArray..newArray[N]. for (int index = _head; index < _items.Length; index++) { newArray = _items; targetIndex++; } // Копируем _items.._items в newArray.. for (int index = 0; index <= _tail; index++) { newArray = _items; targetIndex++; } } else { // Копируем _items.._items в newArray..newArray[N] for (int index = _head; index <= _tail; index++) { newArray = _items; targetIndex++; } } _head = startingIndex; _tail = targetIndex - 1; } else { // Массив пуст. _head = 0; _tail = -1; } _items = newArray; }

Njia ya EnqueueKwanza

  • Tabia: Huongeza kipengele mwanzoni mwa foleni. Kipengele hiki kitachukuliwa kutoka kwa foleni inayofuata wakati mbinu ya DequeueFirst inaitwa.
  • Utata:
utupu wa umma EnqueueFirst(kipengee T) ( // Angalia ikiwa safu inahitaji kuongezwa: ikiwa (_items.Length == _size) ( tengaNewArray(1); ) // Kwa kuwa safu haijajaa na _head ni kubwa kuliko 0, // tunajua kwamba kuna nafasi mwanzoni mwa safu. ikiwa (_kichwa > 0) ( _head--; ) kingine ( // Vinginevyo tunapaswa kuzunguka. _head = _items.Urefu - 1; ) _items[_head] = kipengee; _size++; ikiwa ( _size == 1) ( // Ikiwa tuliongeza kipengele cha kwanza kwenye foleni // tupu, itakuwa pia ya mwisho, kwa hivyo // tunahitaji kusasisha _tail pia. _tail = _head; ) )

EnqueueMbinu ya mwisho

  • Tabia: Huongeza kipengele hadi mwisho wa foleni. Kipengele hiki kitachukuliwa kutoka kwa foleni inayofuata wakati mbinu ya DequeueLast itaitwa.
  • Utata: O(1) katika hali nyingi; O(n) wakati upanuzi wa safu unahitajika.
utupu wa umma EnqueueLast(kipengee T) ( // Angalia ikiwa safu inahitaji kuongezwa: ikiwa (_items.Length == _size) ( tengaNewArray(0); ) // Kwa kuwa sasa tuna safu inayofaa, // ikiwa _tail ni kwenye safu ya mwisho, tunahitaji kwenda kwenye mwanzo. ikiwa (_tail == _items.Urefu - 1) ( _tail = 0; ) mwingine ( _tail++; ) _items[_tail] = item; _size++; ikiwa (_size == 1 ) ( // Ikiwa tuliongeza kipengee cha mwisho kwenye foleni // tupu, itakuwa pia ya kwanza, kwa hivyo // tunahitaji kusasisha _head pia. _head = _tail; ) )

Njia ya DequeueFirst

  • Tabia: Huondoa kipengele kutoka mwanzo wa foleni na kukirejesha. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).
public T DequeueFirst() ( ikiwa (_size == 0) ( tupa InvalidOperationException mpya("Ofa ni tupu"); ) T thamani = _items[_head]; ikiwa (_head == _items.Urefu - 1) ( // Ikiwa kichwa kimewekwa kwenye faharasa ya mwisho, nenda hadi mwanzo wa safu. _head = 0; ) vinginevyo ( // Hamisha hadi kipengele kinachofuata. _head++; ) _size--; thamani ya kurejesha;)

Mbinu ya DequeueLast

  • Tabia: Huondoa kipengele kutoka mwisho wa foleni na kukirejesha. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).
public T DequeueLast() (ikiwa (_size == 0) ( tupa InvalidOperationException mpya("Ofa ni tupu"); ) T thamani = _items[_tail]; ikiwa (_tail == 0) ( // Ikiwa mkia umewekwa kuwa safu ya mwanzo, nenda hadi mwisho.

Mbinu ya PeekFirst

  • Tabia: Hurejesha kipengele kutoka mwanzo wa foleni bila kukibadilisha. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).
public T PeekFirst() ( ikiwa (_size == 0) ( tupa InvalidOperationException mpya("Ofa ni tupu"); ) rudisha _items[_head]; )

Mbinu ya PeekLast

  • Tabia: Hurejesha kipengele kutoka mwisho wa foleni bila kukirekebisha. Ikiwa foleni ni tupu, hutupa InvalidOperationException.
  • Utata: O(1).
public T PeekLast() ( ikiwa (_size == 0) ( tupa InvalidOperationException mpya("Muundo ni tupu"); ) rudisha _items[_tail]; )

Mbinu ya kuhesabu

  • Tabia: Hurejesha idadi ya vipengele kwenye foleni, au 0 ikiwa foleni ni tupu.
  • Utata: O(1).
hesabu ya int ya umma ( pata ( return _size; ) )

Itaendelea

Sasa tumekamilisha sehemu ya nne ya mfululizo wa makala zetu. Ndani yake tuliangalia rundo na foleni. Wakati ujao tutaendelea kwenye miti ya utafutaji ya binary.

Tunatumia lugha za hali ya juu za upangaji ambazo huturuhusu kuandika nambari kidogo na kupata matokeo mazuri. Una kulipa kwa hili. Tunaposhughulika na vitu vya kiwango cha chini kidogo na kidogo, ni kawaida kwamba wengi wetu hatuelewi kabisa mrundikano na lundo ni nini, jinsi mkusanyiko unavyofanya kazi, tofauti ni nini kati ya uchapaji tuli na thabiti, n.k. Sisemi kwamba waandaaji programu wote hawajui kuhusu dhana hizi - nadhani tu kwamba wakati mwingine inafaa kurudi kwenye mambo kama haya ya shule ya zamani.

Leo tutazungumza juu ya mada moja tu: stack na lundo. Rundo na lundo hurejelea maeneo tofauti ambapo usimamizi wa kumbukumbu hutokea, lakini mkakati wa usimamizi huu ni tofauti kabisa.

Rafu

Rafu ni eneo la RAM ambalo limeundwa kwa kila uzi. Inafanya kazi kwa mpangilio wa LIFO (Last In, First Out), ikimaanisha kuwa kipande cha mwisho cha kumbukumbu kinachosukumwa kwenye rafu kitakuwa cha kwanza kwenye mstari kutolewa kwenye rafu. Kila wakati kipengele cha kukokotoa kinapotangaza kigezo kipya, huongezwa kwenye rafu, na kigezo hicho kinapotoka nje ya wigo (kwa mfano, kipengele cha kukokotoa kinapoisha), huondolewa kiotomatiki kutoka kwenye rafu. Tofauti ya rafu inapoachiliwa, eneo hilo la kumbukumbu linapatikana kwa anuwai zingine za rafu.

Kwa sababu ya asili hii ya stack, usimamizi wa kumbukumbu ni mantiki sana na rahisi kufanya juu ya CPU; hii inasababisha kasi ya juu, hasa kwa sababu muda wa mzunguko wa sasisho la stack ni mfupi sana, i.e. Byte hii ina uwezekano mkubwa wa kufungwa kwenye kashe ya processor. Hata hivyo, kuna pia hasara kwa aina hii kali ya usimamizi. Ukubwa wa rafu ni thamani isiyobadilika, na kuzidi kumbukumbu iliyotengwa kwenye rafu kutasababisha kufurika kwa rafu. Ukubwa huwekwa wakati mtiririko unaundwa, na kila kigezo kina ukubwa wa juu kulingana na aina ya data. Hii hukuruhusu kuweka kikomo saizi ya baadhi ya vigeu (kama vile nambari kamili), na kukulazimisha kutangaza ukubwa wa aina changamano zaidi za data (kama vile mkusanyiko) mapema, kwa kuwa rafu haitaziruhusu kuibadilisha. Kwa kuongeza, vigezo vilivyo kwenye stack daima ni vya ndani.

Hatimaye, stack inakuwezesha kudhibiti kumbukumbu kwa njia bora zaidi - lakini ikiwa unahitaji kutumia miundo ya data yenye nguvu au vigezo vya kimataifa, basi unapaswa kuangalia lundo.

Lundo

Lundo ni hifadhi ya kumbukumbu, pia iko katika RAM, ambayo inaruhusu ugawaji wa kumbukumbu unaobadilika na haifanyi kazi kama rundo: ni ghala la vigeu vyako. Unapotenga kipande cha kumbukumbu kwenye lundo ili kuhifadhi kutofautisha, inaweza kufikiwa sio tu kwenye uzi, lakini katika programu yote. Hivi ndivyo vigezo vya kimataifa vinavyofafanuliwa. Wakati programu itaisha, kumbukumbu yote iliyotengwa inatolewa. Ukubwa wa lundo huwekwa wakati programu inapoanza, lakini, tofauti na stack, ni mdogo tu wa kimwili, na hii inakuwezesha kuunda vigezo vinavyobadilika.

Unaingiliana na lundo kupitia marejeleo, ambayo kawaida huitwa viashiria - hizi ni vigeuzo ambavyo maadili yake ni anwani za anuwai zingine. Unapounda kielekezi, unaonyesha eneo la kumbukumbu kwenye lundo, ambalo huweka thamani ya awali ya kutofautisha na kuwaambia programu mahali pa kufikia thamani hiyo. Kwa sababu ya asili ya nguvu ya lundo, CPU haishiriki katika udhibiti wake; Katika lugha bila mtoza takataka (C, C++), msanidi programu anahitaji kuweka bure maeneo ya kumbukumbu ambayo hayahitajiki tena. Ikiwa hii haijafanywa, uvujaji wa kumbukumbu na kugawanyika kunaweza kutokea, ambayo itapunguza kasi ya lundo.

Ikilinganishwa na rundo, lundo ni polepole kwa sababu viambatisho hutawanywa kwenye kumbukumbu badala ya kukaa juu ya rafu. Usimamizi usio sahihi wa kumbukumbu katika lundo husababisha kupungua kwa uendeshaji wake; hata hivyo, hii haipunguzi umuhimu wake - ikiwa unahitaji kufanya kazi na vigezo vinavyobadilika au vya kimataifa, tumia lundo.

Rafu

Rafu ni maarufu zaidi na labda muundo muhimu zaidi wa data katika upangaji programu. Rafu ni kifaa cha kuhifadhi ambacho vitu huondolewa kwa mpangilio wa nyuma wa nyongeza yao. Ni kama foleni isiyo ya kawaida, ambayo wa kwanza kuhudumiwa ni yule aliyeingia mara ya mwisho. Katika fasihi ya programu, vifupisho vinakubaliwa kwa ujumla kuashiria nidhamu ya foleni na stack. Taaluma ya foleni imeteuliwa FIFO, ambayo ina maana ya Kwanza Katika Kati ya Kwanza. Nidhamu ya mrundikano imeteuliwa LIFO, ya mwisho katika ya kwanza kutoka (Mwisho Katika Kwanza).

Rafu inaweza kuzingatiwa kama bomba iliyo na sehemu ya chini iliyopakiwa, iliyowekwa wima. Mwisho wa juu wa bomba umefunguliwa, vitu vinaweza kuongezwa, au, kama wanasema, kusukuma ndani yake. Maneno ya kawaida ya Kiingereza katika suala hili yana rangi nyingi sana; utendakazi wa kuongeza kipengee kwenye rafu huashiria kusukuma, kutafsiriwa kama "sukuma, sukuma." Kipengele kipya kinachoongezwa husukuma vipengele vilivyowekwa hapo awali kwenye rafu chini ya nafasi moja. Wakati vipengele vinapopigwa kutoka kwenye stack, vinasukuma juu, kwa Kiingereza pop ("risasi").

Mfano wa stack itakuwa haystack, stack ya karatasi kwenye meza, stack ya sahani, nk. Hapa ndipo jina la mrundikano linatoka, ambalo linamaanisha mrundikano kwa Kiingereza. Sahani huondolewa kwenye stack kwa utaratibu wa nyuma wa kuongeza kwao. Bamba la juu tu linapatikana, i.e. sahani juu ya stack. Mfano mzuri pia unaweza kuwa mwisho wa reli ambayo magari yanaweza kuwekwa.

Stack hutumiwa mara nyingi kabisa, na katika hali mbalimbali. Wameunganishwa na lengo lifuatalo: unahitaji kuokoa kazi fulani ambayo bado haijakamilika, ikiwa unahitaji kubadili kazi nyingine. Rafu hutumika kuhifadhi kwa muda hali ya kazi ambayo bado haijakamilika. Baada ya kuokoa hali, kompyuta inabadilika kwa kazi nyingine. Baada ya kukamilika kwa utekelezaji wake, hali ya kazi iliyoahirishwa inarejeshwa kutoka kwenye stack, na kompyuta inaendelea operesheni iliyoingiliwa.

Kwa nini mrundikano unatumika kuokoa hali ya kazi iliyokatizwa? Hebu tufikiri kwamba kompyuta inafanya kazi A. Wakati wa utekelezaji wake, haja hutokea kufanya kazi B. Hali ya kazi A inakumbukwa, na kompyuta inaendelea kufanya kazi B. Lakini hata wakati wa kufanya kazi B, kompyuta inaweza kubadili. kwa kazi nyingine C, na itahitaji kuokolewa hali ya kazi B kabla ya kuhamia C. Baadaye, baada ya kukamilika kwa C, hali ya kazi B itarejeshwa kwanza, kisha, baada ya kukamilika kwa B, hali ya kazi A. Kwa hivyo, urejesho hutokea kwa utaratibu wa nyuma wa kuokoa, unaofanana na nidhamu ya stack.



Stack inakuwezesha kuandaa kujirudia, i.e. subroutine inajiita yenyewe, moja kwa moja au kupitia mlolongo wa simu nyingine. Kwa mfano, acha utaratibu wa A utekeleze algoriti ambayo inategemea kigezo cha ingizo X na ikiwezekana na hali ya data ya kimataifa. Kwa maadili rahisi zaidi ya X, algorithm inatekelezwa moja kwa moja. Katika kesi ya maadili magumu zaidi ya X, algorithm inatekelezwa kama kupunguzwa kwa matumizi ya algorithm sawa kwa maadili rahisi ya X. Katika kesi hii, subroutine A inajifikia yenyewe, kupitisha thamani rahisi ya X kama. parameter Kwa upatikanaji huu, thamani ya awali ya parameter X, pamoja na vigezo vyote vya ndani vya utaratibu A huhifadhiwa kwenye stack. Ifuatayo, seti mpya ya vigezo vya ndani na kutofautiana iliyo na thamani mpya (rahisi) ya parameter X huundwa. Subroutine inayoitwa A inafanya kazi kwenye seti mpya ya vigezo bila kuharibu seti ya awali. Mwishoni mwa simu, seti ya zamani ya vigezo vya ndani na hali ya zamani ya parameta ya pembejeo X hurejeshwa kutoka kwa stack, na utaratibu unaendelea kutoka pale ulipoacha.

Kwa kweli, sio lazima hata uhifadhi maadili ya anuwai za kawaida za subroutine kwenye safu kwa njia maalum. Ukweli ni kwamba vigezo vya ndani vya subroutine (yaani, vigezo vyake vya ndani, vinavyofanya kazi, ambavyo vinaundwa mwanzoni mwa utekelezaji wake na kuharibiwa mwishoni) vinawekwa kwenye stack kutekelezwa katika vifaa kulingana na RAM ya kawaida. Mwanzoni kabisa mwa kazi yake, subroutine inachukua nafasi kwenye safu kwa anuwai za kawaida; eneo hili la kumbukumbu kwenye safu ya vifaa kawaida huitwa. kizuizi cha kutofautisha cha ndani au kwa Kiingereza fremu("frame"). Wakati wa kukamilika kwa kazi, subroutine hurusha kumbukumbu kwa kuondoa kizuizi cha vigezo vyake vya ndani kutoka kwa stack.

Kando na vigeu vya ndani, anwani za kurejesha simu za kawaida huhifadhiwa kwenye rafu ya maunzi. Acha utaratibu mdogo uitwe wakati fulani katika programu A B. Kabla ya utaratibu mdogo B kuitwa, anwani ya maagizo yanayofuata maagizo ya kupiga simu B huhifadhiwa kwenye rafu. Hii ndio inayoitwa kurudi anwani kupanga A. Inapokamilika, utaratibu mdogo wa B hutokeza anwani ya kurudi ya programu A kutoka kwenye rafu na kurudisha udhibiti kwenye anwani hiyo. Kwa hivyo, kompyuta inaendelea kutekeleza programu A, kuanzia na maagizo yanayofuata maagizo ya simu. Vichakataji vingi vina maagizo maalum ambayo yanaauni kupiga simu kwa utaratibu mdogo kwa kusukuma kwanza anwani ya kurejesha kwenye rafu na kurejea kutoka kwa utaratibu mdogo kwenye anwani iliyotoka kwenye rafu. Kawaida amri ya simu inaitwa wito, amri ya kurudi inaitwa kurudi.

Vigezo vya utaratibu mdogo au chaguo za kukokotoa pia husukumwa kwenye rafu kabla ya kuitwa. Mpangilio ambao huwekwa kwenye stack inategemea mikataba ya lugha za kiwango cha juu. Kwa hivyo, katika lugha ya C au C ++, hoja ya kwanza ya kazi iko juu ya safu, ya pili iko chini yake, na kadhalika. Katika Pascal, ni kinyume chake: hoja ya mwisho ya chaguo la kukokotoa iko juu ya safu. (Hii ndio sababu, kwa njia, kazi na idadi tofauti ya hoja, kama vile printf, zinawezekana katika C, lakini sio kwa Pascal.)

Katika Fortran-4, moja ya lugha kongwe na iliyofanikiwa zaidi ya programu, hoja hupitishwa kupitia eneo maalum la kumbukumbu, ambalo linaweza kuwa halipo kwenye safu, kwani hadi mwisho wa miaka ya 70 ya karne ya 20 bado kulikuwa na kompyuta kama kompyuta. Kompyuta za IBM 360 au ES zisizo na mrundikano wa utekelezaji wa maunzi. Anwani za kurejesha pia hazikuhifadhiwa kwenye rafu, lakini katika seli za kumbukumbu zilizowekwa kwa kila utaratibu mdogo. Waandaaji programu huita kumbukumbu kama hiyo tuli kwa maana kwamba vigeu vya tuli daima huchukua mahali sawa kwenye kumbukumbu wakati wowote wakati wa utekelezaji wa programu. Wakati wa kutumia kumbukumbu tuli tu, urejeshaji hauwezekani kwa sababu maadili ya awali ya vigezo vya ndani huharibiwa wakati simu mpya inapigwa. Rejea ya Fortran 4 ilitumia vigeuzo tuli tu, na urejeshaji ulipigwa marufuku. Hadi sasa, lugha ya Fortran inatumika sana katika mahesabu ya kisayansi na uhandisi, hata hivyo, kiwango cha kisasa cha Fortran-90 tayari kinaleta kumbukumbu ya stack, kuondoa mapungufu ya matoleo ya awali ya lugha.