Menu
Coddy logo textTech

Stack (מחסנית)

עודכן לאחרונה

מחסנית היא אוסף עם קצה פתוח אחד בלבד. מוסיפים ערך על ידי דחיפה (push) לראש המחסנית, ומסירים ערך על ידי שליפה (pop) של הראש, כך שהערך האחרון שנכנס הוא תמיד הראשון שיוצא. זו המשמעות של LIFO, וזה כל הכלל: אי אפשר להגיע לאמצע בלי להסיר קודם את מה שמעליו. לחצו על הפעלה למעלה וצפו בעמודה שגדלה עם כל push ומתקצרת מאותו קצה עם כל pop.

ההגבלה היא בדיוק העניין. מכיוון ששתי הפעולות נוגעות רק בראש, כל אחת מהן היא O(1) לא משנה כמה גבוהה המחסנית, והצפיוּת הזו היא הסיבה שמחסניות נמצאות מתחת לחלק גדול כל כך של עולם המחשוב: מחסנית הקריאות שמריצה רקורסיה, היסטוריית הביטולים בעורך, התאמת סוגריים במנתח תחבירי, והמחסנית המפורשת שהופכת חיפוש לעומק רקורסיבי ללולאה. אם מחליפים את הקצה שממנו מסירים, מקבלים תור במקום.

סיבוכיות זמן וזיכרון

למחסנית הסטנדרטית שמבוססת על מערך או על רשימה מקושרת:

פעולהסיבוכיותהערות
PushO(1)O(1) בממוצע לשיעורין במערך דינמי, שמדי פעם משנה את גודלו.
PopO(1)תמיד האיבר העליון, ולכן אין צורך להזיז איברים.
Peek (ראש)O(1)קריאת הראש בלי להסיר אותו.
חיפושO(n)לא לשם כך נועדה מחסנית: צריך לשלוף איבר אחרי איבר עד למטה.
זיכרוןO(n)משבצת אחת לכל ערך שמאוחסן.

צעד אחר צעד

צעדמה קורה
1המחסנית מתחילה ריקה, והראש לא מצביע על שום דבר.
2Push כותב את הערך במיקום של הראש ומעלה את הראש במקום אחד.
3כל push נוסף נוחת ישירות מעל הערך הקודם.
4Pop קורא את הערך שבראש, ואז מוריד את הראש במקום אחד.
5הערך שחוזר הוא תמיד זה שנדחף לאחרונה.
6שליפה ממחסנית ריקה היא שגיאה שנקראת stack underflow, ולכן קוד אמיתי בודק קודם is_empty().

דוגמה מפורטת

דחיפה של 3, 7, 5 ואז ריקון המחסנית:

פעולההמחסנית (מלמטה למעלה)מחזירה
push(3)[3]כלום
push(7)[3, 7]כלום
push(5)[3, 7, 5]כלום
pop()[3, 7]5, הערך החדש ביותר
pop()[3]7
pop()[]3, הערך הוותיק ביותר, אחרון

מתי להשתמש במחסנית

כדאי כאשרעדיף להימנע כאשר
צריך לקבל קודם את הפריט האחרון: ביטול פעולות, כפתורי חזרה, התאמת סוגרייםצריך קודם את הפריט הוותיק ביותר, ולשם כך יש תור
הופכים אלגוריתם רקורסיבי לאיטרטיביצריך לחפש או לגשת לפי אינדקס לאמצע הנתונים
מנתחים מבנה מקונן כמו ביטויים, JSON או HTMLקוראים רבים צריכים גישה שרירותית, ושם מערך או מפה מתאימים יותר
רוצים הכנסה והסרה מובטחות ב-O(1) בלי איזון מחדשצריך לשמור את הנתונים ממוינים, וזה מה שערימה או עץ נותנים

קוד Stack

מימוש נקי של Stack שאפשר להריץ, ב-Python, JavaScript, Java, C++, C. בחרו שפה, העתיקו את הקוד, או פתחו אותו טעון מראש בעורך האונליין של Coddy.

קוד Stack ב-Python

Python
1stack = []2
3# Push three values onto the top4for value in [3, 7, 5]:5    stack.append(value)6    print(f"push {value} -> {stack}")7
8# Pop them back off: last in, first out9while stack:10    value = stack.pop()11    print(f"pop  {value} -> {stack}")12
13print("empty:", len(stack) == 0)
להריץ את הקוד הזה בעורך ה-Python אונליין

שאלות נפוצות על מחסנית

מה המשמעות של LIFO?
Last in, first out, כלומר האחרון שנכנס הוא הראשון שיוצא: הערך שנדחף לאחרונה הוא הראשון שנשלף. ערימת צלחות היא הדימוי המוכר, לוקחים את הצלחת שהנחתם הרגע ולא את זו שבתחתית. תור פועל לפי העיקרון ההפוך, FIFO.
מה ההבדל בין מחסנית לתור?
רק הקצה שממנו מסירים. שניהם מוסיפים בקצה אחד ב-O(1); מחסנית מסירה מאותו קצה (LIFO), ותור מסיר מהקצה השני (FIFO). כל השאר, כולל טבלת הסיבוכיות שלמעלה, זהה.
מהן הפעולות העיקריות על מחסנית?
push מוסיפה ערך לראש, pop מסירה ומחזירה את הערך שבראש, peek (לפעמים top) קוראת את הראש בלי להסיר אותו, ו-is_empty מדווחת אם נשאר משהו. כל ארבע הפעולות הן O(1).
מה זה stack overflow?
דחיפה למחסנית שלא נשאר בה מקום. המקרה המפורסם הוא מחסנית הקריאות: כל קריאה לפונקציה דוחפת מסגרת, כך שרקורסיה שלא מגיעה אף פעם למקרה הבסיס ממשיכה לדחוף עד שמגיעים למגבלת המחסנית של סביבת הריצה והתוכנית קורסת. השגיאה ההפוכה, שליפה ממחסנית ריקה, נקראת stack underflow.
איך מממשים מחסנית?
יש שתי דרכים נפוצות. מערך דינמי דוחף ושולף בסוף, וזה O(1) בממוצע לשיעורין וידידותי למטמון: ה-list של Python וה-ArrayDeque של Java עובדים כך. רשימה מקושרת דוחפת ושולפת בראש הרשימה, וזה O(1) גם במקרה הגרוע בלי שינויי גודל, אבל עולה מצביע לכל איבר. ה-std::stack של C++ הוא מתאם שרץ כברירת מחדל על std::deque, מערך מחולק למקטעים, ומקבל מכל אחר אם מעבירים לו אחד.
איפה משתמשים במחסניות בתוכניות אמיתיות?
מחסנית הקריאות לקריאות לפונקציות ולרקורסיה, היסטוריית ביטול וביצוע מחדש, ניווט אחורה בדפדפן, חישוב ביטויים והתאמת סוגריים במנתחים תחביריים, והמחסנית המפורשת שהופכת חיפוש לעומק רקורסיבי ללולאה איטרטיבית.
איור של שפות התכנות ב-Coddy

לשלוט באלגוריתמים עם Coddy

להתחיל