تمثيل بسيط لعمل المكدستمثيل للمكدس
يعرف **المَكْدَس** (بالإنجليزية: Stack)‏ بأنه بنية معطيات مجردة أو مجموعة يمكن فيها القيام بعمليات محددة على العناصر وهي إضافة عنصر جديد إلى المجموعة (تعرف هذه العملية ***بالدفع*** (بالإنجليزية: Push)‏ وإزالة عنصر من المجموعة (تعرف هذه العملية ***بالطرح*** (بالإنجليزية: Pop)‏). تجعل عمليتا الدفع والطرح المكدس بنية معطيات تتمتع بخاصية *من يدخل أخيراً يخرج أولاً* (بالإنجليزية: Last-In-First-Out)‏ أو اختصاراً LIFO. في بنية المعطيات ذات الخاصية LIFO يكون آخر عنصر تم إضافته للمجموعة هو أول عنصر تتم إزالته منها. يعرف المكدس بأنه بنية معطيات متسلسلة تتم فيها عمليات الإضافة والحذف عند نهاية واحدة فقط من السلسلة. عادةً ما يشار إلى آخر عنصر تمت إضافته إلى المكدس باسم ***قمة*** (بالإنجليزية: Top)‏ المكدس كما يزود المكدس بعملية ***استراق*** (بالإنجليزية: Peek)‏ تمكن من معرفة قيمة قمة المكدس دون القيام بإزالته منه.

للمكدس سعة محدودة. فإذا كان المكدس ممتلئاً لا يمكن عندئذ القيام بعملية دفع عنصر إليه، وتسبب محاولة القيام بهذه العملية حصول

طفحان (أو ما يعرف بتجاوز الحد الأعلى للسعة (بالإنجليزية: Overflow)‏). تقوم عملية الطرح بإزالة قمة المكدس وتسبب إما الكشف عن العناصر الموجودة داخل المكدس بالتتابع أو الحصول على مكدس فارغ، إذا كان المكدس فارغاً فإن محاولة القيام بالطرح يسبب حصول تجاوز الحد الأدنى للسعة (بالإنجليزية: Underflow)‏.

يعرف المكدس أيضاً بأنه بنية معطيات *مقيدة*، يعود السبب في ذلك إلى وجود عدد قليل نسبياً من العمليات التي يمكن إجراؤها عليه. كما أن طبيعة عمليات الدفع والطرح تفرض ترتيباً طبيعياً على العناصر. ذلك أن ترتيب حذف العناصر من المكدس يعاكس تماماً ترتيب إضافتها إليه. وبالتالي فإن العناصر الموجودة «أسفل» المكدس ستبقى فترةً أطول من نظيرتها الموجودة بالقرب من قمة المكدس.

تاريخ المكدس
------------

اقترح آلان تورنغ عام 1946 بنية المعطيات المكدس لأول مرة كجزء من تصميمه للكومبيوتر كطريقة لاستدعاء والعودة من الإجراءات الفرعية (وقد استخدم مصطلحات «الدفن» (بالإنجليزية: bury)‏ و«النبش» (بالإنجليزية: unbury)‏ للإشارة إلى هذه العمليات). وقد اقترح الألمانيان كلاوس ساملسن وفريدريش باور من جامعة ميونيخ التقنية بنية المعطيات المكدس عام 1955 وتقدما بطلب براءة اختراع له. وقد اقترح الأسترالي تشارلز لينارد هامبلن المبدأ ذاته عام 1957.

العمليات المجردة
----------------

يعرف المكدس بأنه بنية معطيات بسيطة تتمتع بعدد من العمليات المجردة والتي يمكن تحقيقها بحرية تامة. أو يمكن تعريف المكدس بأنه قائمة خطية من العناصر التي يمكن إضافتها وحذفها عند نهاية واحدة تعرف باسم *القمة*.

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

`init: -> Stack`

`push: N x Stack -> Stack`

`(top: Stack -> (N U ERROR`

`pop: Stack -> Stack`

`isempty: Stack -> Boolean`

حيث يشير N إلى نمط معطيات عناصر المكدس (في هذه الحالة عدد طبيعي)، ويشير U إلى معامل الاجتماع المنطقي.

وفيما يلي معاني هذه العمليات:

`top(init()) = ERROR`

`top(push(i,s)) = i`

`()pop(init()) = init`

`pop(push(i, s)) = s`

`isempty(init()) = true`

`isempty(push(i, s)) = false`

تحقيق المكدس بلغة الباسكال
--------------------------

أبسط طريقة لتعريف المكدس هي استخدام المصفوفة في تمثيل المكدس، سوف نصرح عن المكدس كما في حالة التصريح عن المسجل بلغة الباسكال:

```
Const maxstack = 100;
Type stack = record;
Item : array [1..maxstack] of integer;
Top : 0..maxstack;
Var s:stack

```

من التصريحات المعطاة نجد أن عناصر المكدس `s` الموجودة في المصفوفة `s.item` هي أعداد صحيحة وأن المكدس لن يحتوي على من أكثر من `maxstack` عنصر، ويمكن تغيير عناصر المكدس بتغيير نوع عناصر المصفوفة `s.item`.بما أن `top` هو حقل في المسجل `stack` فإن قيمة المؤشر الذي يدل على عنصر القمة هو `s.top`. إذا كانت قيمة `s.top = 3` فهذا يدل على أن المكدس يحتوي على ثلاثة عناصر هي `s.item[1]` و`s.item[2]` و`s.item[3]`.
إذا طبقنا عملية pop على المكدس فإن قيمة `s.top` يجب أن تعدل لتصبح مساوية 2 ويصبح عنصر القمة هو `[s.item[2`، بينما إذا طبقنا عملية `push` على المكدس فإن قيمة `s.top` يجب أن تعدل لتصبح مساوية 4 ويصبح عنصر القمة هو `[s.item[4`. للبدء بمكدس فارغ يجب أن نكتب: `s.top=0`.
بالاعتماد على ما سبق يمكن كتاية التابع `(empty(s` بلغة الباسكال كما يلي:

```
Function Empty(s:stack) : Boolean;
Begin
 If s.stop = 0 Then empty =true;
 Else empty =false;
End;

```

ويمكن استدعاء هذا التابع بالشكل:

```
If Empty(s)
Then {المكدس فارغ}
Else {المكدس ليس فارغاً}

```

### تحقيق عملية الطرح

ينفذ التابع `(Pop(s` الذي يأخذ بعين الاعتبار حالة كون المكدس فارغ كما يلي:

* إذا كان المكدس فارغاً فإنه يطبع رسالة تدل على الخطأ.
* وإلا يتم سحب عنصر القمة من المكدس وإعطاء هذا العنصر إلى البرنامج المستدعي.

ويكتب هذا التابع بلغة الباسكال كما يلي:

```
Function Pop (var s:stack) : integer
Begin
 If empty(s) Then
 error('stack underflow');
 Else
 Begin
 Pop =s.item[s.top];
 s.top =s.top - 1;
 End;
End;

```

### تحقيق عملية الدفع

يتم ادخال عنصر إلى المكدس عن طريق زيادة s.top بمقدار 1 ومن ثم إدخال x إلى المصفوفة s.item. يُكتب الإجراء الذي يقوم بذلك على الشكل التالي:

```
Procedure push (var s:stack; x:integer)
Begin
 s.top = s.top + 1;
 s.item[s.top] = x;
End;

```

قبل استدعاء الاجراء push يجب التأكد من أن المكدس غير ممتلئ وبالتالي يجب تعديل الجراء السابق بحيث يصبح كالآتي:

```
Procedure Push (var s:stack; x:integer) 
Begin 
If s.top = maxstack Then 
 error('stack overflow');
Else
 Begin 
 s.top = s.top + 1;
 s.item[s.top] = x;
 End;
End;

```

تحقيق المكدس بلغة سي
--------------------

```
#include<stdio.h>
#include<stdlib.h>
 
typedef struct \_StackObject {
 int stack\_top;
 int \*stack;
} StackObject;

int stack\_init(StackObject \*object, int size);
int stack\_destroy(StackObject \*object);
void stack\_push(StackObject \*object, int value);
int stack\_pop(StackObject \*object);
void stack\_inverse(StackObject \*object);

int main(int argc, char \*\*argv) {

 StackObject stack;
 stack\_init(&stack, 10);

 stack\_push(&stack, 11);
 stack\_push(&stack, 22);
 stack\_push(&stack, 33);

 printf("1- %d\n", stack\_pop(&stack));
 printf("2- %d\n", stack\_pop(&stack));
 printf("3- %d\n", stack\_pop(&stack));

 stack\_push(&stack, 11);
 stack\_push(&stack, 22);
 stack\_push(&stack, 33);

 stack\_inverse(&stack);

 printf("1- %d\n", stack\_pop(&stack));
 printf("2- %d\n", stack\_pop(&stack));
 printf("3- %d\n", stack\_pop(&stack));

 stack\_destroy(&stack);
 return(0);
}

int stack\_init(StackObject \*object, int size) {
 object->stack\_top = -1;
 object->stack = (int \*) malloc(sizeof(int) \* size);
 
 if(object->stack == NULL)
 return(-1);
 
 return(0);
}

int stack\_destroy(StackObject \*object) {
 free(object->stack);
 return(0);
}
 
void stack\_push(StackObject \*object, int value) {
 object->stack\_top = object->stack\_top++;
 object->stack[object->stack\_top] = value;
}

int stack\_pop(StackObject \*object) {
 int temp = object->stack[object->stack\_top];
 object->stack\_top = object->stack\_top--;
 return(temp);
}

void stack\_inverse(StackObject \*object) {
 int first = object->stack[0];
 int last = object->stack[object->stack\_top];

 object->stack[0] = last;
 object->stack[object->stack\_top] = first;

 int i;
 for(i = 1 ; i < object->stack\_top ; i++)
 object->stack[object->stack\_top - i] = object->stack[i];
}

```

استخدام المكدس بلغة سي++
------------------------

```
#include <stack>
#include <iostream>

using namespace std;

int main () {
stack <int> a;
int j;
while (1){
cin>>j;
a.push(j);
if (j==0) break;
}
cout<<endl<<"how many elements you wish to delete ? ";
cin>>j;
cout<<endl<<"the last element was "<<a.top();
cout<<endl<<"after the delete ";
for (int i=1;i<=j;i++){
a.pop();
}
cout<<a.top();
return 0;
}

```

انظر أيضاً
----------

* الرتل
* قائمة حزم أباتشي - ماي سيكيول - بي اتش بي

مراجع
-----

1. ↑  منير البعلبكي؛ رمزي البعلبكي (2008). *المورد الحديث: قاموس إنكليزي عربي* (بالعربية والإنجليزية) (ط. 1). بيروت: دار العلم للملايين. ص. 1137. ISBN:978-9953-63-541-5. OCLC:405515532. OL:50197876M. QID:Q112315598.
2. ↑  Newton، David E. (2003). *Alan Turing: a study in light and shadow*. Philadelphia: Xlibris. ص. 82. ISBN:9781401090791. مؤرشف من الأصل في 2017-01-01. اطلع عليه بتاريخ 2015-01-28.
3. ↑  Ball، John A. (1978). *Algorithms for RPN calculators* (ط. 1). Cambridge, Massachusetts, USA: Wiley-Interscience, John Wiley & Sons, Inc. ISBN:0-471-03070-8.`{{استشهاد بكتاب}}`: صيانة الاستشهاد: التاريخ والسنة (link)
4. ↑  IEEE-Computer-Pioneer-Preis -- Bauer, Friedrich L. Technical University of Munich, Faculty of Computer Science, (1 January 1989). "نسخة مؤرشفة". مؤرشف من الأصل في 2017-11-07. اطلع عليه بتاريخ 2017-12-24.

| * ع
* ن
* ت
بنى البيانات |
| --- |
| الأنماط | 
* Collection
* Container

 |
| بنى مجردة | 
* مصفوفة ارتباطية
* Double-ended priority queue
* Double-ended queue
* قائمة
* Multimap
* رتل اولوية
* Queue
* مجموعة
	+ مجموعة
* Disjoint Sets
* المكدس

 |
| بنى مصفوفية | 
* Bit array
* مخزن بيانات مؤقت
* مصفوفة ديناميكية
* جدول تقطيع
* Hashed array tree
* Sparse array

 |
| بنى مترابطة | 
* Association list
* قائمة متصلة
* قائمة متصلة  ‏
* Unrolled linked list
* XOR linked list

 |
| بنى شجرية | 
* بي - تري
* شجرة بحث ثنائية
	+ AA
	+ شجرة AVL
	+ شجرة أحمر-أسود
	+ شجرة بحث ثنائية متزنة
	+ splay
* كومة
	+ binary
	+ binomial
	+ Fibonacci
* R-tree
	+ R\*
	+ R+
	+ Hilbert
* الشجرة الرقمية
	+ Hash tree  ‏

 |
| بنى بيانية | 
* Binary decision diagram
* Directed acyclic word graph

 |
| 
* قائمة ببنى المعطيات

 |

* أيقونة بوابةبوابة برمجة الحاسوب

|  |  |
| --- | --- |
| مشاريع شقيقة | في كومنز صور وملفات عن: مكدس |



|  |  |
| --- | --- |
| ضبط استنادي: وطنية عدلها في ويكي بيانات | 
* الملف الاستنادي المتكامِل (GND)

 |