الخوارزميات الأولية: الترتيب والبحث وتحليل التعقيد

 

الخوارزميات الأولية: الترتيب والبحث وتحليل التعقيد (Sorting, Searching & Complexity Analysis)

الخوارزميات (Algorithms) هي الأساس المنطقي لكل برنامج ناجح — فهي التي تحدد كيفية معالجة البيانات، وتنظيمها، واتخاذ القرارات.
بدون خوارزميات فعالة، تصبح البرامج بطيئة وغير عملية مهما كانت بنيتها قوية.

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

  • خوارزميات الترتيب (Sorting Algorithms)
  • خوارزميات البحث (Searching Algorithms)
  • تحليل التعقيد الزمني والمكاني (Time & Space Complexity)

وسنقدم أمثلة عملية، جداول مقارنة بين الخوارزميات، وروابط موثوقة تساعدك على التوسع في الفهم والتطبيق.


🧩 أولًا: ما هي الخوارزميات؟

الخوارزمية هي مجموعة من الخطوات المنطقية المحددة التي تُستخدم لحل مشكلة معينة أو تنفيذ مهمة ما.

👨‍💻 مثال بسيط:
لإيجاد أكبر رقم في مجموعة أعداد، يمكنك المرور على كل رقم ومقارنته بالأكبر حتى الآن — هذه خوارزمية.

الخوارزميات لا ترتبط بلغة برمجة معينة، بل تُترجم إلى كود في أي لغة مثل Python أو Java أو C++.


⚙️ ثانيًا: خوارزميات الترتيب (Sorting Algorithms)

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

🔹 1. خوارزمية الفقاعات (Bubble Sort)

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

مثال بلغة Python:

arr = [5, 2, 9, 1, 5, 6]

for i in range(len(arr)):
    for j in range(0, len(arr)-i-1):
        if arr[j] > arr[j+1]:
            arr[j], arr[j+1] = arr[j+1], arr[j]

print(arr)

🔸 العيب: بطيئة جدًا مع المجموعات الكبيرة.
🔸 التعقيد: O(n²)


🔹 2. خوارزمية التحديد (Selection Sort)

تعمل عبر البحث عن أصغر عنصر في القائمة ووضعه في الموضع الصحيح في كل دورة.

arr = [29, 10, 14, 37, 14]

for i in range(len(arr)):
    min_index = i
    for j in range(i+1, len(arr)):
        if arr[j] < arr[min_index]:
            min_index = j
    arr[i], arr[min_index] = arr[min_index], arr[i]

print(arr)

🔸 البساطة: سهلة الفهم لكنها غير فعالة مع البيانات الكبيرة.
🔸 التعقيد: O(n²)


🔹 3. خوارزمية الإدراج (Insertion Sort)

تُدخل كل عنصر في مكانه الصحيح كما يفعل الإنسان بترتيب أوراق اللعب.

arr = [12, 11, 13, 5, 6]

for i in range(1, len(arr)):
    key = arr[i]
    j = i - 1
    while j >= 0 and key < arr[j]:
        arr[j + 1] = arr[j]
        j -= 1
    arr[j + 1] = key

print(arr)

🔸 فعالة للبيانات الصغيرة أو شبه المرتبة.
🔸 التعقيد: O(n²)


🔹 4. خوارزمية الدمج (Merge Sort)

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

def merge_sort(arr):
    if len(arr) > 1:
        mid = len(arr)//2
        L = arr[:mid]
        R = arr[mid:]
        merge_sort(L)
        merge_sort(R)
        i = j = k = 0
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1
        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1
        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1

arr = [38, 27, 43, 3, 9, 82, 10]
merge_sort(arr)
print(arr)

🔸 فعالة جدًا للبيانات الكبيرة.
🔸 التعقيد: O(n log n)


🔹 5. خوارزمية الترتيب السريع (Quick Sort)

تعتمد على مبدأ اختيار عنصر محوري (Pivot) وتقسيم القائمة حوله.

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    else:
        pivot = arr[0]
        less = [x for x in arr[1:] if x <= pivot]
        greater = [x for x in arr[1:] if x > pivot]
        return quick_sort(less) + [pivot] + quick_sort(greater)

arr = [10, 7, 8, 9, 1, 5]
print(quick_sort(arr))

🔸 تُعد من أسرع الخوارزميات عمليًا.
🔸 التعقيد: O(n log n)


🔍 ثالثًا: خوارزميات البحث (Searching Algorithms)

تُستخدم هذه الخوارزميات للعثور على عنصر معين داخل البيانات.

🔸 1. البحث الخطي (Linear Search)

يمر على كل عنصر حتى يجد المطلوب.

def linear_search(arr, x):
    for i in range(len(arr)):
        if arr[i] == x:
            return i
    return -1

🔹 البساطة: سهل التنفيذ
🔹 العيب: بطيء في القوائم الكبيرة
🔹 التعقيد: O(n)


🔸 2. البحث الثنائي (Binary Search)

يتطلب قائمة مرتبة مسبقًا ويقسمها في كل خطوة إلى نصفين.

def binary_search(arr, x):
    low = 0
    high = len(arr) - 1
    while low <= high:
        mid = (low + high)//2
        if arr[mid] == x:
            return mid
        elif arr[mid] < x:
            low = mid + 1
        else:
            high = mid - 1
    return -1

🔹 فعالة جدًا للبيانات المرتبة.
🔹 التعقيد: O(log n)


📊 جدول مقارنة بين أهم الخوارزميات

الخوارزمية النوع التعقيد الزمني المميزات العيوب الأفضل للاستخدام
Bubble Sort ترتيب O(n²) سهلة بطيئة البيانات الصغيرة
Merge Sort ترتيب O(n log n) سريعة تحتاج ذاكرة إضافية البيانات الكبيرة
Quick Sort ترتيب O(n log n) فعالة جدًا أداء ضعيف في بعض الحالات البيانات المتوسطة
Linear Search بحث O(n) بسيط بطيء مجموعات صغيرة
Binary Search بحث O(log n) سريع يتطلب بيانات مرتبة قواعد البيانات

🧮 رابعًا: تحليل التعقيد (Complexity Analysis)

كل خوارزمية تُقاس بكفاءتها من خلال:

  • التعقيد الزمني (Time Complexity): كم من الوقت تحتاج؟
  • التعقيد المكاني (Space Complexity): كم من الذاكرة تستهلك؟

الرموز الأساسية المستخدمة:

الرمز المعنى
O(1) ثابت — الأسرع
O(log n) شبه خطي — سريع جدًا
O(n) خطي — يعتمد على حجم البيانات
O(n²) تربيعي — بطيء
O(2ⁿ) أُسي — الأسوأ في الأداء

🧠 خامسًا: أفضل ممارسات تحسين الخوارزميات

  1. ابدأ بالخوارزمية الأبسط ثم طوّرها.
  2. اختبر الأداء على بيانات حقيقية.
  3. استخدم أدوات تحليل مثل Big-O Cheat Sheet.
  4. قس أداءك بالوقت والذاكرة باستخدام مكتبة time في بايثون.
  5. تعلم تحليل التعقيد خطوة بخطوة عبر GeeksforGeeks.

🌐 روابط خارجية موثوقة

 

 

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

Back To Top Img
error: المحتوى محمي !! صقر ويب
Download profile