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

الكومة (الكومة الثنائية)

آخر تحديث

الكومة الثنائية هي شجرة ثنائية كاملة تُبقي أصغر قيمة (الكومة الصغرى) أو أكبر قيمة (الكومة الكبرى) عند الجذر. هذا التصور هو كومة صغرى: كل أب أصغر من أبنائه أو يساويهم. لإضافة قيمة تُلحقها في الموضع الفارغ التالي، ثم "ترشحها للأعلى" بتبديلها مع أبيها ما دامت أصغر، حتى تتحقق خاصية الكومة من جديد. اضغط تشغيل في الأعلى لترى كل قيمة جديدة وهي تصعد إلى مكانها.

بما أن الكومة شجرة كاملة، فإنها تُخزَّن بشكل مضغوط في مصفوفة: أبناء العقدة i يقعان عند 2i+1 و2i+2. الإدراج وإزالة الأصغر بتعقيد O(log n) (مسار واحد من الجذر إلى ورقة)، بينما الاطلاع على الأصغر بتعقيد O(1) - وهو تمامًا ما يحتاجه طابور الأولوية.

التعقيد الزمني والمكاني

العمليةالتعقيدملاحظات
الاطلاع على الأصغر/الأكبرO(1)إنه دائمًا الجذر
الإدراج (push)O(log n)الترشيح للأعلى عبر مسار
إزالة الأصغر/الأكبرO(log n)الترشيح للأسفل عبر مسار
بناء الكومةO(n)heapify دفعة واحدة
المساحةO(n)قائمة على مصفوفة، بلا مؤشرات

خطوة بخطوة (push)

الخطوةماذا يحدث
1ألحق القيمة الجديدة في النهاية (الورقة الفارغة التالية).
2قارنها بأبيها.
3إذا كانت أصغر (الكومة الصغرى)، بدّلها للأعلى.
4كرّر حتى لا تعود أصغر من أبيها أو تبلغ الجذر.

مثال محلول

بناء كومة صغرى بإدراج [5, 3, 8, 1, 4] قيمة تلو الأخرى:

Pushالمصفوفة بعد الترشيح للأعلىالإجراء
5[5]تصبح القيمة الأولى الجذر.
3[3, 5]3 < الأب 5، لذا تصعد حتى الجذر.
8[3, 5, 8]8 > الأب 5، لذا تبقى ورقة.
1[1, 3, 8, 5]1 < الأب 5، تبديل؛ ثم 1 < الأب 3، تصعد حتى الجذر.
4[1, 3, 8, 5, 4]4 > الأب 3، لذا تبقى؛ ويظل الأصغر 1 عند الجذر.

متى تستخدم الكومة

استخدمها عندماتجنبها عندما
تحتاج مرارًا إلى أصغر أو أكبر عنصر من مجموعة متغيرة.تحتاج إلى البحث عن قيم اعتباطية، لا الطرف فقط - استخدم شجرة بحث ثنائية أو مجموعة تجزئة.
تنفّذ طابور أولوية لخوارزمية Dijkstra أو ‎A*‎ أو مجدول.تحتاج إلى إبقاء البيانات مرتبة كاملًا في كل الأوقات.
تريد الإدراج وإزالة الأصغر بتعقيد O(log n) مع تخطيط مصفوفة مضغوط.تحتاج إلى بحث أو حذف سريع لعنصر محدد (غير الجذر).
تحتاج إلى دمج تدفق من العناصر وسحبها حسب الأولوية.مجموعة البيانات صغيرة جدًا والمسح الخطي أبسط وسريع بما يكفي.

كود Heap (Priority Queue)

تنفيذ نظيف وقابل للتشغيل لخوارزمية Heap (Priority Queue) بلغات Python, JavaScript, Java, C++, C. اختر لغة، وانسخ الكود، أو افتحه محمّلًا مسبقًا في ساحة تجربة Coddy.

كود Heap (Priority Queue) بلغة Python

Python
1class MinHeap:2    def __init__(self):3        self.data = []4
5    def push(self, value):6        # Append at the end, then bubble up to restore order7        self.data.append(value)8        i = len(self.data) - 19        while i > 0:10            parent = (i - 1) // 211            if self.data[parent] <= self.data[i]:12                break13            self.data[i], self.data[parent] = self.data[parent], self.data[i]14            i = parent15
16    def pop(self):17        # Move the last leaf to the root, then sift it down18        top = self.data[0]19        last = self.data.pop()20        if self.data:21            self.data[0] = last22            self._sift_down(0)23        return top24
25    def _sift_down(self, i):26        n = len(self.data)27        while True:28            smallest = i29            left, right = 2 * i + 1, 2 * i + 230            if left < n and self.data[left] < self.data[smallest]:31                smallest = left32            if right < n and self.data[right] < self.data[smallest]:33                smallest = right34            if smallest == i:35                return36            self.data[i], self.data[smallest] = self.data[smallest], self.data[i]37            i = smallest38
39
40heap = MinHeap()41for value in [5, 3, 8, 1, 9, 2]:42    heap.push(value)43
44print("Heap array:     ", heap.data)45print("Popped in order:", [heap.pop() for _ in range(6)])
شغّل هذا الكود في ساحة تجربة Python

أسئلة شائعة عن الكومة

فيمَ تُستخدم الكومة؟
تنفّذ الكوم طوابير الأولوية، التي تشغّل خوارزمية أقصر مسار لـ Dijkstra، ومجدولات المهام، ومحاكاة الأحداث. وهي أيضًا المحرك وراء فرز الكومة (heapsort). كلما احتجت مرارًا إلى أصغر أو أكبر عنصر من مجموعة متغيرة، فالكومة هي الأداة المناسبة.
ما الفرق بين الكومة وشجرة البحث الثنائية؟
كلاهما شجرتان ثنائيتان، لكن شجرة البحث الثنائية تحافظ على ترتيب كامل من اليسار إلى اليمين (يتيح بحثًا مرتبًا)، بينما تضمن الكومة علاقة الأب بالابن فقط (الأصغر أو الأكبر عند الجذر). تمنح الكومة وصولًا بتعقيد O(1) إلى القيمة الطرفية؛ وتمنح شجرة البحث الثنائية بحثًا بتعقيد O(log n) لأي قيمة.
لماذا تُخزَّن الكومة في مصفوفة؟
بما أن الكومة دائمًا شجرة ثنائية كاملة، فإن عقدها تُطابق فهارس المصفوفة تمامًا: أبناء الفهرس i يقعان عند 2i+1 و2i+2، والأب عند (i-1)/2. هذا يتجنب تخزين مؤشرات الأبناء ويمنح أداء ذاكرة تخزين مؤقت ممتازًا.
هل الكومة مثل المصفوفة المرتبة؟
لا. تضمن الكومة فقط أن كل أب أصغر (الكومة الصغرى) أو أكبر (الكومة الكبرى) من أبنائه، لذا لا ترتيب معيّن للإخوة وأبناء العم. المصفوفة المرتبة مرتبة كاملًا لكن الإدراج فيها يكلف O(n)، بينما تُدرج الكومة بتعقيد O(log n) وتظل تمنح وصولًا فوريًا إلى القيمة الطرفية.
متى ينبغي استخدام الكومة بدلًا من مجرد فرز مصفوفة؟
لجأ إلى الكومة عندما تتغير البيانات باستمرار ولا تحتاج إلا إلى الأصغر أو الأكبر الحالي - يكلف الإدراج والسحب O(log n) لكلٍّ منهما، مقابل إعادة فرز المصفوفة كلها. أما إذا كانت لديك مجموعة بيانات ثابتة وتريد كل العناصر مرتبة، ففرزة واحدة بتعقيد O(n log n) أبسط وغالبًا أسرع.
هل بناء كومة من n عنصرًا يستغرق O(n log n)؟
ليس إذا بنيتها دفعة واحدة. إدراج n عنصرًا واحدًا تلو الآخر بتعقيد O(n log n)، لكن heapify من الأسفل إلى الأعلى، الذي يرشّح للأسفل من آخر أب حتى الجذر، يعمل بتعقيد O(n) إجمالًا، لأن معظم العقد قريبة من القاع وترشّح للأسفل مسافة قصيرة فقط.
Coddy programming languages illustration

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

ابدأ الآن