Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

المكدس (Stack)

آخر تحديث

المكدس مجموعة لها طرف مفتوح واحد فقط. تضيف قيمة بدفعها إلى القمة، وتزيل قيمة بسحب القمة مرة أخرى، فتكون آخر قيمة دخلت هي أول قيمة تخرج دائمًا. هذا هو معنى LIFO، وهو القاعدة كلها: لا سبيل إلى بلوغ المنتصف دون إزالة ما فوقه أولًا. اضغط على تشغيل في الأعلى وشاهد العمود ينمو مع كل دفع وينكمش من الطرف نفسه مع كل سحب.

القيد نفسه هو المقصود. لأن العمليتين لا تلمسان إلا القمة، فكل واحدة منهما O(1) مهما ارتفع المكدس، وهذه القابلية للتنبؤ هي سبب وقوف المكدس تحت هذا القدر الكبير من الحوسبة: مكدس الاستدعاءات الذي يشغّل التعاود، وسجل التراجع في المحرر، ومطابقة الأقواس في المحلّل، والمكدس الصريح الذي يحوّل البحث بالعمق أولاً التعاودي إلى حلقة. بدّل طرف الإزالة وستحصل على الطابور بدلًا منه.

تعقيد الوقت والمساحة

للمكدس القياسي المبني على مصفوفة أو على قائمة مترابطة:

العمليةالتعقيدملاحظات
الدفع (push)O(1)مُستهلَكة عند O(1) على مصفوفة ديناميكية تُعيد التحجيم من حين لآخر.
السحب (pop)O(1)دائمًا عنصر القمة، فلا حاجة إلى أي إزاحة.
الاطّلاع على القمة (peek)O(1)قراءة القمة دون إزالتها.
البحثO(n)ليس هذا ما وُجد المكدس له: عليك السحب نزولًا حتى تصل.
المساحةO(n)خانة واحدة لكل قيمة مخزَّنة.

خطوة بخطوة

الخطوةما الذي يحدث
1يبدأ المكدس فارغًا، والقمة لا تشير إلى شيء.
2يكتب الدفع القيمة في موضع القمة ويحرّك القمة درجة واحدة للأعلى.
3كل دفع تالٍ يستقر مباشرة فوق القيمة السابقة.
4يقرأ السحب القيمة عند القمة، ثم يحرّك القمة درجة واحدة للأسفل.
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؟
الوارد أخيرًا يخرج أولًا: آخر قيمة جرى دفعها هي أول قيمة تُسحب. كومة الأطباق هي الصورة المعتادة، إذ تأخذ الطبق الذي وضعته للتو لا الطبق الذي في القاع. الطابور هو الانضباط المعاكس، أي FIFO.
ما الفرق بين المكدس والطابور؟
الطرف الذي تزيل منه فقط. كلاهما يضيف عند طرف واحد بـ O(1)، لكن المكدس يزيل من الطرف نفسه (LIFO) بينما يزيل الطابور من الطرف الآخر (FIFO). وكل ما عدا ذلك، بما في ذلك جدول التعقيد أعلاه، متطابق.
ما هي عمليات المكدس الأساسية؟
تضيف push قيمة إلى القمة، وتزيل pop قيمة القمة وتعيدها، وتقرأ peek (وتسمى أحيانًا top) القمة دون إزالتها، ويخبرك is_empty بما إذا كان قد بقي شيء. العمليات الأربع كلها O(1).
ما هو فيضان المكدس؟
الدفع إلى مكدس لم يعد فيه متسع. الحالة الأشهر هي مكدس الاستدعاءات: كل استدعاء دالة يدفع إطارًا، لذا فإن التعاود الذي لا يبلغ حالته الأساسية يستمر في الدفع حتى يبلغ حد المكدس في بيئة التشغيل فيتعطل البرنامج. والخطأ المعاكس، أي سحب مكدس فارغ، هو نقص المكدس (stack underflow).
كيف يُنفَّذ المكدس؟
هناك طريقتان شائعتان. المصفوفة الديناميكية تضيف وتزيل من النهاية، وذلك O(1) مُستهلَكة وصديقة لذاكرة التخزين المؤقت: هكذا تعمل list في بايثون و ArrayDeque في جافا. القائمة المتصلة تضيف وتزيل من الرأس، وذلك O(1) في أسوأ الحالات دون إعادة تحجيم، لكنها تكلف مؤشرًا لكل عنصر. وفي C++ std::stack هو مُحوِّل يعمل افتراضيًا فوق std::deque، وهي مصفوفة مجزأة، ويقبل حاوية أخرى إذا مررتها.
أين تُستخدم المكدسات في البرامج الحقيقية؟
مكدس الاستدعاءات لاستدعاءات الدوال و التعاود، وسجل التراجع والإعادة، والتنقل للخلف في المتصفح، وتقييم التعابير ومطابقة الأقواس في المحلّلات، والمكدس الصريح الذي يحوّل البحث بالعمق أولاً التعاودي إلى حلقة تكرارية.
Coddy programming languages illustration

أتقن الخوارزميات مع Coddy

ابدأ الآن