جامعة حمص - كلية الهندسة المعلوماتية

أشجار البحث الثنائية (BST)

المحاضرة السادسة عشر - خوارزميات وبنى معطيات 1

إعداد: د. ناديا خرسان
العام الدراسي: 2023-2024
المادة: خوارزميات وبنى معطيات 1
التعريف والخصائص
العمليات الأساسية
البحث
الإضافة
الحذف

تعريف أشجار البحث الثنائية (BST)

شجرة البحث الثنائية (BST) هي شجرة ثنائية تحقق الشروط التالية:

  • كل عقدة لها قيمة مفتاحية (key) مميزة (لا توجد قيم مكررة)
  • القيم في الشجرة الفرعية اليسارية أصغر من قيمة الجذر
  • القيم في الشجرة الفرعية اليمينية أكبر من قيمة الجذر
  • كل من الشجرة الفرعية اليسارية واليمينية هي شجرة بحث ثنائية

التمثيل الرياضي

لكل عقدة V:
جميع القيم في اليسار < V < جميع القيم في اليمين

أمثلة على أشجار BST وأشجار غير BST

شجرة BST صحيحة

In-order: 5, 15, 22, 30, 35, 60, 70, 80

شجرة غير BST

In-order: 12, 15, 10, 22, 25, 30

(10 < 12 لكنها في اليمين)

خصائص BST

  • عند التنقل باستخدام In-order نحصل على القيم مرتبة تصاعدياً
  • البحث والإضافة والحذف يتم في وقت O(h) حيث h ارتفاع الشجرة
  • في الحالة المتوازنة يكون h = O(log n)
  • في الحالة الأسوأ (شجرة خطية) يكون h = O(n)

العمليات الأساسية على BST

البحث (Search)

البحث عن قيمة محددة في الشجرة

التعقيد: O(h)
الإضافة (Insertion)

إضافة عقدة جديدة مع الحفاظ على خصائص BST

التعقيد: O(h)
الحذف (Deletion)

حذف عقدة مع الحفاظ على خصائص BST

التعقيد: O(h)
القيم القصوى (Min/Max)

إيجاد أصغر أو أكبر قيمة في الشجرة

التعقيد: O(h)

هيكل البيانات في C++

struct

Node {

    

int

data;

    

struct

Node* left;

    

struct

Node* right;

};


typedef struct

Node* BST;

الإضافة إلى شجرة BST

خوارزمية الإضافة إلى شجرة BST:

  1. ابدأ من الجذر
  2. إذا كانت الشجرة فارغة، أنشئ عقدة جديدة كجذر
  3. قارن القيمة مع العقدة الحالية
  4. إذا كانت أصغر، انتقل إلى اليسار
  5. إذا كانت أكبر، انتقل إلى اليمين
  6. عند الوصول إلى NULL، أضف العقدة الجديدة

مثال توضيحي: إضافة القيم 8, 4, 6, 15

التنفيذ باستخدام العودية

void

insertNode(BST &root,

int

x) {

    

if

(root ==

NULL

) {

        root =

new

Node();

        root->data = x;

        root->left = root->right =

NULL

;

    }

    

else

if

(x == root->data)

        

return

;

    

else

if

(x < root->data)

        insertNode(root->left, x);

    

else

        insertNode(root->right, x);

}

إيجاد القيم القصوى

أصغر قيمة (Minimum)

Node

* minNode(BST root) {

    

while

(root->left !=

NULL

)

        root = root->left;

    

return

root;

}

أكبر قيمة (Maximum)

Node

* maxNode(BST root) {

    

while

(root->right !=

NULL

)

        root = root->right;

    

return

root;

}

الحذف من شجرة BST

عند حذف عقدة من شجرة BST، هناك ثلاث حالات:

1. حذف عقدة ورقية

قم بحذف العقدة مباشرة

2. حذف عقدة لها ابن واحد

استبدل العقدة بابنها

3. حذف عقدة لها ابنان

استبدل العقدة بأكبر قيمة في اليسار أو أصغر قيمة في اليمين

التنفيذ باستخدام العودية

BST

deleteNode(BST root,

int

x) {

    

if

(root ==

NULL

)

return

root;


    

if

(x < root->data)

        root->left = deleteNode(root->left, x);

    

else

if

(x > root->data)

        root->right = deleteNode(root->right, x);

    

else

{

        

// الحالة 1: عقدة بدون أبناء أو بعمر واحد

        

if

(root->left ==

NULL

) {

            BST temp = root->right;

            

delete

root;

            

return

temp;

        }

else

if

(root->right ==

NULL

) {

            BST temp = root->left;

            

delete

root;

            

return

temp;

        }


        

// الحالة 2: عقدة لها ابنان

        BST temp = minNode(root->right);

        root->data = temp->data;

        root->right = deleteNode(root->right, temp->data);

    }

    

return

root;

}

ارتفاع شجرة BST

  • إذا تم إضافة العناصر مرتبة: h = n-1 (شجرة خطية)
  • إذا تم إضافة العناصر بشكل عشوائي: h = O(log n)
  • في الحالة المتوسطة: h ≈ 1.39 log₂ n