C Academy · درس

الاجتياز والبحث

المرور على القائمة

الدرس 3 من 413 خطوة

الاجتياز والبحث درس مجاني في C Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C Academy 4 دروس في المجموع.

التجوّل في القائمة

يعني التجوال زيارة كل عقدة بالترتيب. تبدأ من الرأس وتتبع مؤشرات next حتى تصل إلى NULL.

تعتمد كل خوارزميات القوائم تقريبًا على هذا التجوّل البسيط.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

int main(void) {
    struct Node *head = make(10);
    head->next = make(20);
    for (struct Node *p = head; p != NULL; p = p->next)
        printf("%d ", p->value);
    printf("\n");
    return 0;
}

نمط التجوّل

تستخدم الحلقة القياسية مؤشرًا متحركًا p: تهيّئه إلى head، وتتابع التنفيذ ما دام p ليس NULL، ثم تقدّمه باستخدام p = p->next.

لا تعدّل head نفسه أثناء التجوّل، وإلا فقدت بداية القائمة.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

int main(void) {
    struct Node *head = make(1);
    head->next = make(2);
    struct Node *p = head;
    while (p) { printf("%d ", p->value); p = p->next; }
    printf("\n");
    return 0;
}

عدّ العقد

لإيجاد طول القائمة، تجوّل فيها وزِد عدّادًا بمقدار واحد لكل عقدة.

هذه عملية تعقيدها O(n)، لأن العدد غير مخزّن في أي موضع.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

int length(struct Node *head) {
    int n = 0;
    for (struct Node *p = head; p; p = p->next) n++;
    return n;
}

int main(void) {
    struct Node *head = make(1);
    head->next = make(2);
    head->next->next = make(3);
    printf("length = %d\n", length(head));
    return 0;
}

جمع القيم

يتيح لك التجوّل تجميع البيانات. سنجمع هنا كل القيم الصحيحة الموجودة في القائمة.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

int main(void) {
    struct Node *head = make(5);
    head->next = make(10);
    int sum = 0;
    for (struct Node *p = head; p; p = p->next) sum += p->value;
    printf("sum = %d\n", sum);
    return 0;
}

البحث عن قيمة

للعثور على قيمة، تجوّل في القائمة وقارن كل عقدة. أعد العقدة (أو موضعها) عند العثور على تطابق، أو أشر إلى فشل العملية إذا وصلت إلى النهاية.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

struct Node *find(struct Node *head, int v) {
    for (struct Node *p = head; p; p = p->next)
        if (p->value == v) return p;
    return NULL;
}

int main(void) {
    struct Node *head = make(1);
    head->next = make(2);
    printf("found 2: %d\n", find(head, 2) != NULL);
    printf("found 9: %d\n", find(head, 9) != NULL);
    return 0;
}

العثور على موضع

قد تحتاج أحيانًا إلى فهرس العنصر المطابق بدلًا من العقدة نفسها. احتفظ بعدّاد أثناء التجوّل، وأعد قيمته عند العثور على القيمة.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

int index_of(struct Node *head, int v) {
    int i = 0;
    for (struct Node *p = head; p; p = p->next, i++)
        if (p->value == v) return i;
    return -1;
}

int main(void) {
    struct Node *head = make(7);
    head->next = make(8);
    printf("%d\n", index_of(head, 8));
    return 0;
}

الوصول إلى العقدة رقم n

لا توفر القوائم المرتبطة وصولًا مباشرًا باستخدام الفهرس. للوصول إلى الموضع n، يجب أن تتقدم n مرة بدءًا من الرأس.

لذلك يكون الوصول العشوائي بتعقيد O(n)، مقارنةً بتعقيد O(1) في المصفوفة.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

struct Node *at(struct Node *head, int n) {
    struct Node *p = head;
    for (int i = 0; i < n && p; i++) p = p->next;
    return p;
}

int main(void) {
    struct Node *head = make(10);
    head->next = make(20);
    head->next->next = make(30);
    printf("%d\n", at(head, 2)->value);
    return 0;
}

العثور على العقدة الأخيرة

للوصول إلى الذيل، تجوّل حتى يصبح p->next مساويًا لـ NULL. تلك العقدة هي الأخيرة.

انتبه إلى القائمة الفارغة، حيث يكون head نفسه مساويًا لـ NULL.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

int main(void) {
    struct Node *head = make(1);
    head->next = make(2);
    head->next->next = make(3);
    struct Node *p = head;
    while (p->next) p = p->next;
    printf("last = %d\n", p->value);
    return 0;
}

العثور على القيمة العظمى

من خلال الجمع بين البحث والتجميع، يمكنك العثور على أكبر قيمة بتتبّع أفضل قيمة حاليًا أثناء التجوّل.

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

int main(void) {
    struct Node *head = make(3);
    head->next = make(9);
    head->next->next = make(5);
    int best = head->value;
    for (struct Node *p = head->next; p; p = p->next)
        if (p->value > best) best = p->value;
    printf("max = %d\n", best);
    return 0;
}

التجوّل التعاودي

يمكن أيضًا التجوّل في القوائم بطريقة تعاودية: عالج العقدة الحالية، ثم نفّذ الاستدعاء التعاودي على next.

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

#include <stdio.h>
#include <stdlib.h>

struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}

void print_rec(struct Node *p) {
    if (!p) { printf("\n"); return; }
    printf("%d ", p->value);
    print_rec(p->next);
}

int main(void) {
    struct Node *head = make(1);
    head->next = make(2);
    print_rec(head);
    return 0;
}

التعامل مع القوائم الفارغة

يجب أن تتعامل كل دالة للتجوّل مع القائمة الفارغة (head == NULL) بسلاسة.

تتعامل الحلقة القياسية معها تلقائيًا: إذ يكون الشرط p != NULL خاطئًا مباشرة، فلا يُنفّذ جسم الحلقة.

#include <stdio.h>

struct Node { int value; struct Node *next; };

int length(struct Node *head) {
    int n = 0;
    for (struct Node *p = head; p; p = p->next) n++;
    return n;
}

int main(void) {
    struct Node *head = NULL;
    printf("empty length = %d\n", length(head));
    return 0;
}

تحقق سريع

اختبر مدى فهمك لتكلفة التجوّل في القائمة.

مراجعة

تعلّمت التجوّل في القوائم والبحث فيها:

  • نمط التجوّل: ابدأ من head، وكرّر ما دام ليس NULL، ثم تقدّم باستخدام p = p->next.
  • يعتمد العد والجمع والعثور على القيمة العظمى على التجوّل.
  • يقارن البحث كل عقدة؛ والوصول باستخدام الفهرس تعقيده O(n).
  • يمكن أن يكون التجوّل تَعاوديًا، لكن التكرار أكثر أمانًا للقوائم الطويلة؛ واحرص دائمًا على معالجة الحالة الفارغة.
البدء مجانًا

تعلم C مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
39
الدروس
144

الأسئلة الشائعة

هل درس «الاجتياز والبحث» مجاني؟

نعم — نص درس «الاجتياز والبحث» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C Academy 4 دروس في المجموع.

ماذا ستتعلم في «الاجتياز والبحث»؟

المرور على القائمة تتمرن على C Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C Academy؟

لا تُشترط خبرة سابقة. C Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «الاجتياز والبحث»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C Academy هذا؟

نعم. كل درس في C Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. القوائم المرتبطة أحادية الاتجاه
  2. الإدراج والحذف
  3. الاجتياز والبحث
  4. القوائم المرتبطة ثنائية الاتجاه
← العودة إلى C Academy