المحاضرة الرابعة عشر - خوارزميات وبنى معطيات 1
الشجرة الثنائية هي مجموعة منتهية من العقد، إما أن تكون خالية أو مكونة من:
نسمي البنية B شجرة ثنائية إذا تحقق أحد الشرطين:
أو
حيث B1 هي الشجرة الفرعية اليسارية و B2 هي الشجرة الفرعية اليمينية.
مثال: إذا كان ارتفاع الشجرة (h) = 3
حيث:
البرهان:
لنفرض أن n حجم الشجرة، و n1 عدد العقد من الدرجة 1
n = n0 + n1 + n2 ... (1)
عدد الحواف في الشجرة b = n - 1
لكل عقدة من الدرجة 2 تساهم بحافتين، ومن الدرجة 1 بحافة واحدة:
n - 1 = n1 + 2n2 ... (2)
بالتعويض من (1) و (2) نصل إلى: n0 = n2 + 1
كل عقدة لها على الأكثر ولد واحد
كل عقدة لها إما صفر أو ولدين بالضبط
جميع المستويات ممتلئة إلا الأخير، والفراغات من جهة اليمين
جميع المستويات ممتلئة تمامًا بالعقد
| النوع | الوصف | الاستخدامات |
|---|---|---|
| خطية | تتحول إلى قائمة مرتبطة | تمثيل التسلسلات الخطية |
| ممتلئة | لا توجد عقدة بولد واحد فقط | خوارزميات الضغط والتشفير |
| كاملة | الفراغات في المستوى الأخير من اليمين فقط | بنى الكومة (Heaps) |
| تامة | جميع العقد الورقية بنفس المستوى | الأنظمة المتوازنة، أشجار القرار |
نستخدم مصفوفة بأحجام 2h+1 - 1 حيث h ارتفاع الشجرة
// مثال كود لإنشاء شجرة باستخدام المصفوفات
#define
MAX_SIZE
15
char
tree[
MAX_SIZE
];
// تعيين الجذر
tree[1] =
'A'
;
// تعيين الأبناء
tree[2] =
'B'
; // الابن الأيسر لـ A
tree[3] =
'C'
; // الابن الأيمن لـ A
كل عقدة تمثل ككائن يحتوي على:
struct
Node {
int
data;
struct
Node* left;
struct
Node* right;
};
typedef struct
Node* BTree;
// إنشاء عقدة جديدة
struct
Node* createNode(
int
data) {
struct
Node* node = (
struct
Node*)
malloc
(
sizeof
(
struct
Node));
node->data = data;
node->left =
NULL
;
node->right =
NULL
;
return
node;
}
| المعيار | المصفوفات | القوائم المترابطة |
|---|---|---|
| الكفاءة في الذاكرة | منخفضة للأشجار غير الكاملة | عالية (تستخدم الذاكرة حسب الحاجة) |
| سرعة الوصول | O(1) للوصول العشوائي | O(n) للوصول العشوائي |
| إضافة/حذف العقد | معقد ويتطلب إعادة تنظيم | سهل وسريع (O(1)) |
| الاستخدام الأمثل | الأشجار الكاملة والتامة | جميع أنواع الأشجار |
حيث ⌊x⌋ هو أكبر عدد صحيح ≤ x
حيث n₂ هو عدد العقد التي لها ولدان
حيث ⌈x⌉ هو أصغر عدد صحيح ≥ x