الإدراج في BST
أنشئ شجرة بحث ثنائية
الإدراج في BST درس مجاني في C Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C Academy 4 دروس في المجموع.
قاعدة ترتيب شجرة البحث الثنائية
شجرة البحث الثنائية (BST) هي شجرة ثنائية لها قاعدة إضافية: تكون جميع القيم في الشجرة الفرعية اليسرى أصغر من قيمة كل عقدة، وجميع القيم في الشجرة الفرعية اليمنى أكبر منها.
ويتيح لنا هذا الترتيب البحث والإدراج والحذف في زمن يتناسب مع ارتفاع الشجرة.
موضع القيمة
للإدراج، نبدأ من الجذر ونقارن. إذا كانت القيمة الجديدة أصغر، نتجه يسارًا؛ وإذا كانت أكبر، نتجه يمينًا.
نكرر ذلك حتى نصل إلى موضع فارغ (NULL)، وهو الموضع الذي تنتمي إليه العقدة الجديدة تمامًا.
/* insert 7 into:
* 10
* / \
* 5 15
* 7 < 10 -> left; 7 > 5 -> right of 5
*/الدالة المساعدة create_node
ينشئ الإدراج عقدًا ورقية جديدة، لذلك نعيد استخدام مُنشئ يخصّص العقدة ويهيّئها.
يبدأ الابنان بقيمة NULL لأن العقدة المُدرجة حديثًا تكون دائمًا ورقة.
Node *create_node(int value) {
Node *n = malloc(sizeof(Node));
if (!n) return NULL;
n->value = value;
n->left = n->right = NULL;
return n;
}الإدراج التكراري
أنظف طريقة للإدراج هي الطريقة التكرارية التي تعيد جذر الشجرة الفرعية، سواء أكان جديدًا أم لا.
إذا كانت الشجرة الفرعية فارغة، نعيد عقدة جديدة. وإلا نكرر العملية في اليسار أو اليمين ونعيد ربط النتيجة، ثم نعيد الجذر الذي لم يتغير.
Node *insert(Node *root, int value) {
if (root == NULL)
return create_node(value);
if (value < root->value)
root->left = insert(root->left, value);
else if (value > root->value)
root->right = insert(root->right, value);
return root; /* equal: ignore duplicate */
}لماذا نعيد الجذر
يتيح إرجاع جذر الشجرة الفرعية للأب إعادة ربط المؤشر في سطر واحد: root->left = insert(root->left, v).
عندما تكون الشجرة الفرعية فارغة، تصبح العقدة الجديدة المُعادة ابنًا لها. وعندما لا تكون فارغة، يُعاد الجذر نفسه ويبقى الرابط دون تغيير.
/* The assignment does double duty:
* - empty case: stores the new node
* - non-empty: stores the same pointer back (no-op)
*/
root->left = insert(root->left, value);معالجة القيم المكررة
يجب أن تحدد أشجار البحث الثنائية الحقيقية كيفية التعامل مع القيم المتساوية. ومن الخيارات الشائعة تجاهل القيم المكررة، كما تفعل insert لدينا بعدم تخصيص فرع لحالة التساوي.
وتشمل البدائل الاحتفاظ بعدّاد لكل عقدة أو إرسال القيم المكررة دائمًا إلى أحد الجانبين.
if (value < root->value)
root->left = insert(root->left, value);
else if (value > root->value)
root->right = insert(root->right, value);
/* value == root->value -> do nothing */بناء شجرة بحث ثنائية
ينتج عن إدراج سلسلة من القيم شجرة يعتمد شكلها على ترتيب الإدراج.
نُدرج هنا عدة أعداد ونطبع الابنين المباشرين للجذر للتأكد من تحقق قاعدة الترتيب.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node { int value; struct Node *left, *right; } Node;
Node *create_node(int v){ Node *n=malloc(sizeof(Node)); n->value=v; n->left=n->right=NULL; return n; }
Node *insert(Node *r,int v){
if(!r) return create_node(v);
if(v<r->value) r->left=insert(r->left,v);
else if(v>r->value) r->right=insert(r->right,v);
return r;
}
int main(void){
Node *root = NULL;
int data[] = {10,5,15,3,7};
for(int i=0;i<5;i++) root=insert(root,data[i]);
printf("root=%d left=%d right=%d\n", root->value, root->left->value, root->right->value);
return 0;
}إدراج تكراري
يمكنك أيضًا إجراء الإدراج من دون تكرار. نسير إلى الأسفل باستخدام مؤشر، مع الاحتفاظ بالأب، حتى نعثر على موضع فارغ.
ثم نربط العقدة الجديدة بالجانب الصحيح من ذلك الأب.
void insert_iter(Node **rootp, int value) {
Node *cur = *rootp, *parent = NULL;
while (cur) {
parent = cur;
cur = (value < cur->value) ? cur->left : cur->right;
}
Node *n = create_node(value);
if (!parent) *rootp = n;
else if (value < parent->value) parent->left = n;
else parent->right = n;
}ترتيب الإدراج يشكّل الشجرة
يؤدي إدراج 1,2,3,4,5 بترتيب تصاعدي إلى شجرة متدهورة تشبه قائمة مرتبطة، ويكون ارتفاعها مساويًا لعدد العناصر.
أما الإدراج بترتيب متوازن فيُبقي الارتفاع قريبًا من log(n). ويؤثر التوازن مباشرةً في سرعة البحث.
/* sorted insert 1..5 ->
* 1
* \
* 2
* \
* 3 (height = 4, like a list)
*/كلفة الإدراج
يسلك كل إدراج مسارًا واحدًا من الجذر إلى ورقة، لذلك يتطلب عملًا يتناسب مع ارتفاع الشجرة.
في الشجرة المتوازنة يعادل ذلك تقريبًا log(n) من المقارنات، أما في الشجرة المتدهورة فقد يصل إلى n. ولهذا السبب توجد الأشجار ذاتية التوازن.
عرض توضيحي كامل للإدراج
يدرج هذا البرنامج القيم، ثم يعدّ العُقد للتأكد من تخزين خمس قيم مميزة وتجاهل قيمة مكررة.
لا تزيد القيمة المكررة 10 العدد، لأن insert يتجاهل القيم المتساوية.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node { int value; struct Node *left, *right; } Node;
Node *cn(int v){ Node *n=malloc(sizeof(Node)); n->value=v; n->left=n->right=NULL; return n; }
Node *insert(Node *r,int v){
if(!r) return cn(v);
if(v<r->value) r->left=insert(r->left,v);
else if(v>r->value) r->right=insert(r->right,v);
return r;
}
int count(Node *r){ return r? 1+count(r->left)+count(r->right):0; }
int main(void){
Node *root=NULL;
int d[]={10,5,15,10,20};
for(int i=0;i<5;i++) root=insert(root,d[i]);
printf("count=%d\n", count(root));
return 0;
}تحقق سريع
حلّل سلوك الإدراج.
مراجعة
تقارن عملية الإدراج في BST القيمة الجديدة بكل عقدة، فتتجه إلى اليسار للقيمة الأصغر وإلى اليمين للقيمة الأكبر، حتى تعثر على موضع فارغ.
تعيد الصيغة التكرارية جذر الشجرة الفرعية، كي يتمكن الأب من إعادة ربط المؤشرات بصورة سليمة. تتناسب تكلفة الإدراج مع ارتفاع الشجرة، لذلك يهم ترتيب الإدراج.
الأسئلة الشائعة
هل درس «الإدراج في BST» مجاني؟
نعم — نص درس «الإدراج في BST» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C Academy 4 دروس في المجموع.
ماذا ستتعلم في «الإدراج في BST»؟
أنشئ شجرة بحث ثنائية تتمرن على C Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C Academy؟
لا تُشترط خبرة سابقة. C Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «الإدراج في BST»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C Academy هذا؟
نعم. كل درس في C Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- عُقد الشجرة وبنيتها
- الإدراج في BST
- عمليات الاجتياز
- البحث والتحرير