بنية بيانات الكومة: ما هي الكومة؟

⚡ ملخص ذكي

بنية بيانات الكومة هي شجرة ثنائية كاملة متخصصة حيث تحافظ كل عقدة أصلية على علاقة ترتيب صارمة مع أبنائها، مما يتيح عمليات الإدخال والحذف اللوغاريتمية وعمليات قائمة الانتظار ذات الأولوية عبر عمليات الفرز والجدولة وأحمال العمل الرسومية.

  • 🌳 شكل الشجرة: الكومة عبارة عن شجرة ثنائية كاملة مملوءة من اليسار إلى اليمين، مع مفاتيح فريدة في كل عقدة للمقارنة السريعة.
  • ⬆️ ماكس هيب: كل عنصر أب أكبر من أو يساوي أبنائه، لذلك فإن أكبر عنصر يقع دائمًا في الجذر للوصول O(1).
  • ⬇️ الحد الأدنى للكومة: كل والد أقل من أو يساوي أبنائه، حافظping أصغر عنصر في الجذر لاسترجاع الأولوية.
  • ✅ جوهر Operaنشوئها: يتم تشغيل عمليات البحث والإدراج والحذف والتكديس والدمج في وقت O(log n)، مع دعم منطق فرز الكومة وقائمة الانتظار ذات الأولوية.
  • 🧪 الاستخدامات الحقيقية: تدعم بنية بيانات الكومة تصفية البريد العشوائي، وخوارزميات الرسوم البيانية، وجدولة نظام التشغيل، وتشفير هوفمان، والبحث الاستدلالي للذكاء الاصطناعي.

ما هي بنية بيانات الكومة؟

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

بعبارات بسيطة، الكومة هي شجرة ثنائية كاملة تحقق خاصية الكومة: كل أصل مرتب بشكل متسق مقابل أبنائه، مما يجعلها مثالية لقوائم الانتظار ذات الأولوية وفرز الكومة.

لماذا تحتاج إلى بنية بيانات الكومة؟

فيما يلي الأسباب الرئيسية لاستخدام الكومة:

  • تسمح بنية بيانات الكومة بالحذف والإدراج في وقت لوغاريتمي – O(log2ن).
  • تُرتّب البيانات في الشجرة وفق ترتيب مُحدد. وإلى جانب تحديث القيم أو الاستعلام عنها، مثل القيم القصوى أو الدنيا، يستطيع المبرمج إيجاد العلاقات بين الأصل والفرع.
  • يمكنك تطبيق مفهوم طراز كائن المستند لمساعدتك على فهم بنية بيانات الكومة بصريًا.
  • تدعم الأكوام عمليات قائمة الانتظار ذات الأولوية الفعالة، والتي تعتبر بالغة الأهمية لخوارزميات الرسم البياني مثل أقصر مسار لـ Dijkstra وشجرة الامتداد الأدنى لـ Prim.

أنواع الأكوام

تتضمن بنية بيانات الكومة خوارزميات متنوعة لمعالجة عمليات إدخال وحذف العناصر، بما في ذلك قائمة الانتظار ذات الأولوية، والكومة الثنائية، والكومة ذات الحدين، و نوع كومة.

  • طابور الأولوية: إنها عضلات بطنtracبنية بيانات تحتوي على كائنات ذات أولوية. لكل كائن أو عنصر أولوية محددة مسبقًا. لذلك، يحصل الكائن أو العنصر ذو الأولوية الأعلى على الخدمة قبل غيره.
  • الكومة الثنائية: تُعدّ الأكوام الثنائية مناسبة لعمليات الكومة البسيطة مثل الحذف والإضافة. وهي التنفيذ الافتراضي لمعظم قوائم الانتظار ذات الأولوية في المكتبات القياسية.
  • كومة ذات الحدين: تتكون الكومة الثنائية من سلسلة من مجموعات الأشجار الثنائية التي تشكل الكومة. شجرة الكومة الثنائية ليست شجرة عادية، إذ أنها محددة بدقة. يساوي العدد الإجمالي للعناصر في الشجرة الثنائية دائمًا 2^12.n العقد.
  • فرز الكومة: على عكس معظم خوارزميات الفرز، يستخدم فرز الكومة مساحة ثابتة O(1) لعملية الفرز. وهي خوارزمية فرز قائمة على المقارنة، حيث يتم الفرز بترتيب تصاعدي عن طريق تحويل المدخلات أولاً إلى كومة عظمى. ويمكن اعتبار فرز الكومة بمثابة نسخة مطورة من شجرة البحث الثنائية.

عادةً، تستخدم بنية بيانات الكومة استراتيجيتين. بالنسبة للمدخلات 12 – 8 – 4 – 2 و 1:

  • كومة صغيرة – أقل قيمة في الأعلى
  • أقصى كومة – أعلى قيمة في القمة

أنواع الأكوام

كومة صغيرة

في بنية الكومة الدنيا، تكون قيمة العقدة الجذرية إما مساوية أو أصغر من قيمة أبناء تلك العقدة. لذا، فإن جذر الكومة الدنيا يحمل القيمة الدنيا. كما أن الكومة الدنيا عبارة عن شجرة ثنائية كاملة.

بمجرد الحصول على كومة دنيا في الشجرة، تصبح جميع الأوراق مرشحة للحصول على القيمة القصوى. مع ذلك، يجب فحص كل ورقة على حدة للحصول على قيمة كومة قصوى دقيقة.

مثال على كومة الحد الأدنى

مثال على الحد الأدنى من الكومة

في الرسم التخطيطي أعلاه، يمكنك ملاحظة تسلسل واضح من الجذر إلى العقدة الأدنى.

لنفترض أنك تخزن العناصر في المصفوفة Array_N[12, 2, 8, 1, 4]. كما تلاحظ من المصفوفة، فإن العنصر الجذر يخالف أولوية كومة الحد الأدنى. للحفاظ على خاصية كومة الحد الأدنى، عليك إجراء عمليات تحويل كومة الحد الأدنى لتبديل العناصر حتى يتم استيفاء قواعد كومة الحد الأدنى.

أقصى كومة

في بنية كومة القيم القصوى، تحتوي العقدة الأب أو الجذرية على قيمة مساوية أو أكبر من قيمة أبنائها. تحمل هذه العقدة القيمة القصوى. وهي شجرة ثنائية كاملة، لذا يمكنك بناء كومة قيم قصوى من مجموعة من القيم في زمن O(n).

فيما يلي بعض الطرق الشائعة الاستخدام عند تنفيذ Java ماكس هيب:

  • يضيف (): يضع عنصرًا جديدًا في كومة. إذا كنت تستخدم مصفوفة، تتم إضافة العناصر في نهاية المصفوفة، بينما في الشجرة الثنائية، تتم إضافة العناصر من الأعلى إلى الأسفل ثم من اليسار إلى اليمين.
  • يزيل (): تتيح لك هذه الطريقة إزالة العنصر الأول من قائمة المصفوفة. ولأن العنصر الذي تمت ترقيته حديثًا لم يعد الأكبر، فإن طريقة Sift-Down تقوم دائمًا بنقله إلى موقعه الجديد.
  • Sift-Down (): تقوم هذه الطريقة بمقارنة الكائن الجذر بأبنائه ثم تدفع العقدة التي تم نقلها إلى موضعها الصحيح.
  • Sift-Up (): إذا استخدمتَ طريقة المصفوفة لإضافة عنصر جديد إلى مصفوفة، فإن طريقة Sift-Up تساعد العنصر المُضاف حديثًا على الانتقال إلى موضعه الصحيح. تتم مقارنة العنصر الجديد أولًا بالعنصر الأصل له عن طريق محاكاة بنية بيانات الشجرة.

    قم بتطبيق الصيغة Parent_Index = Child_Index / 2. استمر في القيام بذلك حتى يصبح العنصر الأقصى في مقدمة المصفوفة.

الكومة الأساسية Operaستعقد

للعثور على أعلى وأدنى القيم في مجموعة بيانات، تحتاج إلى بعض عمليات الذاكرة الأساسية مثل البحث والإضافة والحذف. ولأن العناصر تتغير باستمرار، يجب أن تعرف كيفية القيام بما يلي:

  • - ابحث عن عنصر في الكومة.
  • إدراج - إضافة طفل جديد إلى الكومة.
  • حذف - حذف عقدة من الكومة.

إنشاء أكوام

تُعرف عملية إنشاء الأكوام باسم إنشاء الأكوام. عند إعطاء قائمة من المفاتيح، يقوم المبرمج بإنشاء كومة فارغة ثم يُدخل المفاتيح الأخرى واحدًا تلو الآخر باستخدام عمليات الكومة الأساسية.

لنبدأ الآن ببناء كومة دنيا باستخدام طريقة ويليام عن طريق إدخال القيم 12، 2، 8، 1، و4. يمكنك بناء الكومة التي تحتوي على n عنصرًا عن طريق البدء بكومة فارغة ثم ملؤها تباعًا بعناصر أخرى باستخدام وقت O(n log n).

إنشاء أكوام

  • هيبيفاي: روتين إدخال يساعد في إدخال العناصر في كومة مع الحفاظ على خاصية الكومة.

    على سبيل المثال، تتحقق عملية بناء كومة قصوى من أن قيمة العنصر الأب أكبر من قيمة العنصر الابن. ويمكن بعد ذلك فرز العناصر باستخدام طرق مثل التبديل.ping.

  • دمج: عندما يكون لديك مجموعتان من البيانات لدمجهما في مجموعة واحدة، استخدم عملية الدمج لجمع القيم من المجموعتين معًا. تبقى المجموعات الأصلية محفوظة.

فحص أكوام

يشير فحص الأكوام إلى التحقق من عدد العناصر في بنية بيانات الكومة والتحقق مما إذا كانت الكومة فارغة.

من المهم فحص أكوام البيانات أثناء فرز العناصر أو إضافتها إلى قائمة الانتظار. من الضروري التحقق من وجود عناصر للمعالجة باستخدام الدالة IsEmpty(). يساعد حجم الكومة في تحديد جذور الكومة القصوى أو الكومة الدنيا، لذا يجب معرفة عدد العناصر التي تتبع خاصية الكومة.

  • المقاس – تُعيد هذه الدالة حجم أو طول الكومة. وتُخبرك بعدد العناصر المخزنة بترتيب مُرتب.
  • Is-Empty – تُرجع القيمة TRUE إذا كانت الكومة فارغة، وإلا فإنها تُرجع القيمة FALSE.

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

//print head the head values
       While (!priorityQ.isEmpty()) {
        System.out.print(priorityQ.poll()+" ");

استخدامات بنية بيانات الكومة

تُعد بنية بيانات الكومة مفيدة في العديد من تطبيقات البرمجة في الحياة الواقعية، مثل:

  • يساعد في تصفية الرسائل غير المرغوب فيها.
  • تطبيق خوارزميات الرسوم البيانية مثل خوارزمية ديكسترا وخوارزمية بريم.
  • Operaموازنة أحمال النظام وضغط البيانات.
  • إيجاد إحصائيات الترتيب مثل أصغر عنصر في الرتبة k.
  • تطبيق قوائم الانتظار ذات الأولوية حيث يمكنك البحث عن العناصر في قائمة في وقت لوغاريتمي.
  • تُستخدم بنية بيانات الكومة أيضًا للفرز من خلال فرز الكومة.
  • محاكاة العملاء في طابور الانتظار.
  • معالجة المقاطعات في نظام التشغيل.
  • في ترميز هوفمان لضغط البيانات.
  • دعم البحث الأفضل أولاً وخوارزميات A* في تخطيط مسار الذكاء الاصطناعي.

خصائص قائمة انتظار أولوية الكومة

تصف الخصائص التالية كيفية عمل قائمة الانتظار ذات الأولوية المبنية على كومة:

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

خطوات تنفيذ قائمة انتظار أولوية الكومة في Java

القسم التالي ينتقل إلى موضوع ملموس Java تطبيق يحول هذه القواعد إلى كود برمجي فعال.

خطوات تنفيذ قائمة انتظار أولوية الكومة

فرز الكومة في Java مع Code مثال

import java.util.Arrays;
public class HeapSort {
    public static void main(String[] args) {
        int[] arr = {5, 9, 3, 1, 8, 6};
        // Sort the array using heap sort
        heapSort(arr);
        // Print the sorted array
        System.out.println(Arrays.toString(arr));
    }
    public static void heapSort(int[] arr) {
        // Convert the array into a heap
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            heapify(arr, arr.length, i);
        }
        // Extract the maximum element from the heap and place it at the end of the array
        for (int i = arr.length - 1; i >= 0; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            heapify(arr, i, 0);
        }
    }
    public static void heapify(int[] arr, int n, int i) {
        int largest = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        // Find the largest element among the root, left child, and right child
        if (left < n && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < n && arr[right] > arr[largest]) {
            largest = right;
        }
        // If the largest element is not the root, swap and heapify the sub-tree
        if (largest != i) {
            int temp = arr[i];
            arr[i] = arr[largest];
            arr[largest] = temp;
            heapify(arr, n, largest);
        }
    }
}

الناتج

Original Array:

5 9 3 1 8 6

Heap after insertion:

9 8 6 1 5 3

Heap after sorting:

1 3 5 6 8 9

فرز الكومة في Python مع Code مثال

def heap_sort(arr):
    """
    Sorts an array in ascending order using heap sort algorithm.
    Parameters:
        arr (list): The array to be sorted.
    Returns:
        list: The sorted array.
    """
    n = len(arr)
    # Build a max heap from the array
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)
    # Extract elements from the heap one by one
    for i in range(n - 1, 0, -1):
        arr[0], arr[i] = arr[i], arr[0]  # swap the root with the last element
        heapify(arr, i, 0)  # heapify the reduced heap
    return arr
def heapify(arr, n, i):
    """
    Heapifies a subtree with the root at index i in the given array.
    Parameters:
        arr (list): The array containing the subtree to be heapified.
        n (int): The size of the subtree.
        i (int): The root index of the subtree.
    """
    largest = i  # initialize largest as the root
    left = 2 * i + 1  # left child index
    right = 2 * i + 2  # right child index
    # If left child is larger than root
    if left < n and arr[left] > arr[largest]:
        largest = left
    # If right child is larger than largest so far
    if right < n and arr[right] > arr[largest]:
        largest = right
    # If largest is not root
    if largest != i:
        arr[i], arr[largest] = (
            arr[largest],
            arr[i],
        )  # swap the root with the largest element
        heapify(arr, n, largest)  # recursively heapify the affected subtree
arr = [4, 1, 3, 9, 7]
sorted_arr = heap_sort(arr)
print(sorted_arr)

الناتج

[1, 3, 4, 7, 9]

بعد ذلك، ستتعرف على طريقة التنصيف.

الأسئلة الشائعة

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

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

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

تُعتبر خوارزمية فرز الكومة خوارزميةً مُدمجةً لأنها تُرتّب المصفوفة باستخدام ذاكرة إضافية ثابتة (O(1)) تتجاوز حجم المدخلات. وهي غير مستقرة، إذ يُمكن أن تتبادل المفاتيح المتساوية ترتيبها النسبي أثناء عملية التجميع والتوسيع.tracعدد الخطوات القصوى (t-max) المستخدمة لإنتاج المخرجات المصنفة.

تخزن خوارزميات البحث في الذكاء الاصطناعي، مثل خوارزمية A* وخوارزمية البحث الأفضل أولاً، عقد الحدود في كومة دنيا مُفهرسة بتكلفة استدلالية. تضمن هذه الكومة توسيع المرشح الأقل تكلفة تالياً، وهو أمر بالغ الأهمية لإيجاد المسارات بسرعة، والذكاء الاصطناعي للألعاب، ومخططات الروبوتات.

نعم. يمكن لبرامج العرض المرئي المدعومة بالذكاء الاصطناعي إنشاء مخططات تفصيلية لعمليات الإدخال، وتبديلات الكومة، وما إلى ذلك.tracتُتيح لك هذه الأدوات إمكانية تحديد عمليات t-max من التعليمات البرمجية الخاصة بك. كما أنها تُشير إلى انتهاكات خصائص الذاكرة الديناميكية، وتقترح حلولاً، وتشرح السلوك التقاربي بلغة بسيطة، مما يُسرّع عملية التعلم وتصحيح الأخطاء.

تلخيص هذه التدوينة بـ: