QuickSort: دليل شامل لخوارزمية الفرز السريع في بايثون وجافا (مع تحليل الأداء)

استمع للبودكاست حوار شيق بين لمى وأبو عمر
0:00 / 0:00

مقدمة: عندما أضعت مفاتيح السيارة… والـ QuickSort!

بتذكر مرة، كنت مستعجل كتير عشان ألحق موعد مهم. نزلت من البيت، وفتحت الباب، بس وين المفاتيح؟ 🤦‍♂️ دورت بكل جيوبي، بالكنبايات، تحت السجاد… حرفياً قلبت البيت فوقاني تحتاني! بالنهاية، اكتشفت إنهم كانوا جوا الثلاجة! (لا تسألوني كيف وصلوا هناك 😂). هاي التجربة علمتني شغلة مهمة: الترتيب والتنظيم بيوفروا وقت وجهد كبيرين. ونفس الشي بينطبق على البيانات في عالم البرمجة. وهون بيجي دور خوارزميات الفرز، وبالأخص خوارزمية الـ QuickSort اللي رح نحكي عنها اليوم.

الـ QuickSort هي خوارزمية فرز قوية وفعالة، تعتمد على مبدأ “فرق تسد” (Divide and Conquer). بتعتبر من أسرع خوارزميات الفرز الموجودة، وبتستخدم على نطاق واسع في تطبيقات مختلفة. في هالمقالة، رح نتعمق في طريقة عملها، ونحلل أدائها، ونطبقها عملياً في لغتي بايثون وجافا.

ما هي خوارزمية QuickSort؟

الـ QuickSort هي خوارزمية فرز مقارنة (comparison-based sorting algorithm) بتقسم المصفوفة (array) لمجموعتين أصغر، ثم بتقوم بفرز كل مجموعة بشكل مستقل. الفكرة الرئيسية بتعتمد على اختيار عنصر محوري (pivot) من المصفوفة، ثم إعادة ترتيب العناصر بحيث تكون كل العناصر الأصغر من المحور على يساره، وكل العناصر الأكبر منه على يمينه. بعد هيك، بنكرر نفس العملية على المجموعتين الأصغر بشكل متكرر (recursive) لحتى نحصل على مصفوفة مرتبة.

كيف تعمل الـ QuickSort خطوة بخطوة؟

  1. اختيار المحور (Pivot Selection): بنختار عنصر من المصفوفة ليكون هو المحور. ممكن نختار العنصر الأول، أو الأخير، أو أي عنصر عشوائي.
  2. التقسيم (Partitioning): بنعيد ترتيب العناصر في المصفوفة بحيث تكون كل العناصر الأصغر من المحور على يساره، وكل العناصر الأكبر منه على يمينه.
  3. التكرار (Recursion): بنطبق نفس العملية (التقسيم والفرز) على المجموعتين الأصغر (المجموعة اللي على يسار المحور، والمجموعة اللي على يمينه) بشكل متكرر لحتى نحصل على مصفوفة مرتبة.

تحليل أداء QuickSort

أداء الـ QuickSort بيعتمد بشكل كبير على كيفية اختيار المحور. في أفضل الحالات (best case) والحالات المتوسطة (average case)، بيكون الأداء O(n log n)، بينما في أسوأ الحالات (worst case) بيكون الأداء O(n^2).

  • أفضل الحالات (Best Case): بيحدث لما نختار المحور بحيث يقسم المصفوفة لمجموعتين متساويتين تقريباً في كل مرة.
  • الحالات المتوسطة (Average Case): بيحدث لما نختار المحور بشكل عشوائي، أو لما يكون توزيع البيانات في المصفوفة عشوائي.
  • أسوأ الحالات (Worst Case): بيحدث لما نختار المحور بحيث يكون هو أصغر أو أكبر عنصر في المصفوفة في كل مرة. في هالحالة، بنضطر لفرز مصفوفة بحجم n-1 عنصر في كل مرة، مما يؤدي لأداء O(n^2).

نصيحة من أبو عمر: حاول دائماً تختار المحور بشكل عشوائي، أو استخدم طريقة “Median-of-Three” لاختيار المحور. هاي الطرق بتقلل بشكل كبير من احتمالية الوصول لأسوأ الحالات.

تطبيق QuickSort في بايثون

هاد مثال كود بسيط لتطبيق QuickSort في بايثون:


def quicksort(arr):
  if len(arr) <= 1:
    return arr
  pivot = arr[len(arr) // 2]
  left = [x for x in arr if x  pivot]
  return quicksort(left) + middle + quicksort(right)

# مثال للاستخدام
arr = [3, 6, 8, 10, 1, 2, 1]
sorted_arr = quicksort(arr)
print("Sorted array:", sorted_arr) # Output: Sorted array: [1, 1, 2, 3, 6, 8, 10]

تطبيق QuickSort في جافا

وهاد مثال كود مماثل لتطبيق QuickSort في جافا:


public class QuickSort {

    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int pi = partition(arr, low, high);

            quickSort(arr, low, pi - 1);
            quickSort(arr, pi + 1, high);
        }
    }

    static int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = (low - 1);

        for (int j = low; j <= high - 1; j++) {
            if (arr[j] < pivot) {
                i++;
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;
        return (i + 1);
    }

    public static void main(String[] args) {
        int[] arr = {3, 6, 8, 10, 1, 2, 1};
        quickSort(arr, 0, arr.length - 1);

        System.out.print("Sorted array: ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        // Output: Sorted array: 1 1 2 3 6 8 10
    }
}

نصائح لتحسين أداء QuickSort

هون بعض النصائح اللي ممكن تساعدك لتحسين أداء الـ QuickSort:

  • اختيار المحور العشوائي (Random Pivot Selection): زي ما ذكرت قبل، اختيار المحور بشكل عشوائي بيقلل من احتمالية الوصول لأسوأ الحالات.
  • استخدام Insertion Sort للمصفوفات الصغيرة: الـ Insertion Sort بيكون أسرع من الـ QuickSort للمصفوفات الصغيرة. ممكن تستخدم الـ Insertion Sort لما يكون حجم المصفوفة أقل من قيمة معينة (مثلاً 10 أو 20 عنصر).
  • تحسين عملية التقسيم (Partitioning Optimization): ممكن تحسن عملية التقسيم عن طريق استخدام تقنيات مثل Hoare’s Partitioning Scheme.

الخلاصة: QuickSort صديقك في عالم الفرز!

الـ QuickSort هي خوارزمية فرز قوية وفعالة، وبتعتبر من الأدوات الأساسية اللي لازم تكون موجودة في جعبة كل مبرمج. تعلمناها اليوم، وحللنا أدائها، وطبقناها عملياً في بايثون وجافا. بتمنى تكون هالمقالة فادتكم، وإذا عندكم أي سؤال، لا تترددوا تسألوا. 👍

نصيحة أخيرة من أبو عمر: لا تخاف تجرب وتعدل على الكود. البرمجة تعلم بالممارسة والتجربة. حاول تطبق الـ QuickSort على مشاكل مختلفة، وشوف كيف ممكن تحسن أدائها. بالتوفيق! 🚀

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

ادارة الفرق والتنمية البشرية

من جحيم الاعتماد على شخص واحد إلى ذاكرة فريق جماعية: قصة نجاحنا مع سجلات قرارات الهندسة (ADRs)

هل تعاني من حبس المعرفة التقنية في عقل شخص واحد في فريقك؟ أشارككم قصة حقيقية حول كيف كاد هذا الأمر أن يدمر مشروعنا، وكيف أنقذتنا...

15 أبريل، 2026 قراءة المزيد
أتمتة العمليات

فريقنا كان يغرق في النقرات: كيف أنقذتنا ‘أتمتة العمليات الروبوتية’ (RPA) من جحيم المهام اليدوية؟

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

15 أبريل، 2026 قراءة المزيد
ذكاء اصطناعي

نماذجنا اللغوية كانت تهلوس: كيف أنقذنا ‘الاسترجاع المعزز للتوليد’ (RAG) من جحيم الإجابات الخاطئة؟

أشارككم قصة حقيقية من أرض الميدان عن "هلوسة" نماذج الذكاء الاصطناعي وكيف أصبحت تقنية الاسترجاع المعزز للتوليد (RAG) طوق النجاة. هذا دليل عملي، من مبرمج...

15 أبريل، 2026 قراءة المزيد
خوارزميات

حساباتنا كانت تعيد اختراع العجلة: كيف أنقذتنا البرمجة الديناميكية من جحيم التكرار؟

أشارككم قصة من قلب المعركة البرمجية، حين كانت خوادمنا تئن تحت وطأة التكرار، وكيف كانت "البرمجة الديناميكية" طوق النجاة. تعالوا نكتشف معًا هذا المفهوم القوي...

15 أبريل، 2026 قراءة المزيد
تسويق رقمي

ميزانيتنا كانت تتبخر: كيف أنقذتنا ‘نماذج الإحالة المبنية على البيانات’ من جحيم تخمين عائد الاستثمار؟

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

15 أبريل، 2026 قراءة المزيد
البودكاست