0Pricing
C Academy · درس

استخدام qsort

ترتيب المكتبة القياسية

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

دالة الفرز في المكتبة القياسية

توفر المكتبة القياسية للغة C الدالة qsort في <stdlib.h>. وهي تفرز أي مصفوفة عند تزويدها بـ دالة مقارنة، لذلك نادرًا ما تحتاج إلى كتابة خوارزمية فرز خاصة بك.

توقيع qsort

النموذج الأولي هو:

  • base مؤشر إلى العنصر الأول
  • nmemb عدد العناصر
  • size عدد البايتات لكل عنصر
  • compar مؤشر إلى دالة مقارنة

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

كتابة دالة مقارنة

تستقبل دالة المقارنة قيمتين من النوع const void *. حوّلهما إلى النوع الفعلي، ثم أزل الإشارة عنهما وأعد قيمة سالبة أو صفرًا أو قيمة موجبة.

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

int cmp_int(const void *a, const void *b) {
    int x = *(const int *)a;
    int y = *(const int *)b;
    return (x > y) - (x < y); /* safe, no overflow */
}

int main(void) {
    int a[] = {5, 2, 9, 1, 3};
    qsort(a, 5, sizeof(int), cmp_int);
    for (int i = 0; i < 5; i++) printf("%d ", a[i]);
    printf("\n");
    return 0;
}

تجنّب الطرح في دوال المقارنة

قد يؤدي إرجاع x - y إلى تجاوز السعة عند التعامل مع أعداد صحيحة كبيرة، مما ينتج عنه نتائج خاطئة. استخدم بدلًا منه تعبير الفرق بين القيم المنطقية (x > y) - (x < y).

#include <stdio.h>

int main(void) {
    int x = 2000000000, y = -2000000000;
    printf("unsafe x-y = %d\n", x - y);          /* overflow */
    printf("safe        = %d\n", (x > y) - (x < y));
    return 0;
}

الترتيب التنازلي

للفرز تنازليًا، اعكس نتيجة المقارنة فحسب.

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

int cmp_desc(const void *a, const void *b) {
    int x = *(const int *)a, y = *(const int *)b;
    return (y > x) - (y < x);
}

int main(void) {
    int a[] = {5, 2, 9, 1, 3};
    qsort(a, 5, sizeof(int), cmp_desc);
    for (int i = 0; i < 5; i++) printf("%d ", a[i]);
    printf("\n");
    return 0;
}

فرز السلاسل النصية

لفرز مصفوفة من النوع char *، تستقبل دالة المقارنة مؤشرات إلى المؤشرات. حوّلها إلى const char * const * واستدعِ strcmp.

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

int cmp_str(const void *a, const void *b) {
    const char *x = *(const char * const *)a;
    const char *y = *(const char * const *)b;
    return strcmp(x, y);
}

int main(void) {
    const char *names[] = {"charlie", "alice", "bob"};
    qsort(names, 3, sizeof(char *), cmp_str);
    for (int i = 0; i < 3; i++) printf("%s ", names[i]);
    printf("\n");
    return 0;
}

فرز البنى

يمكنك فرز مصفوفة من البنى وفقًا لأي حقل. نرتّب الأشخاص هنا حسب العمر.

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

typedef struct { char name[16]; int age; } Person;

int by_age(const void *a, const void *b) {
    const Person *p = a, *q = b;
    return (p->age > q->age) - (p->age < q->age);
}

int main(void) {
    Person ppl[] = {{"Ann", 30}, {"Ben", 25}, {"Cid", 40}};
    qsort(ppl, 3, sizeof(Person), by_age);
    for (int i = 0; i < 3; i++) printf("%s %d\n", ppl[i].name, ppl[i].age);
    return 0;
}

الفرز متعدد المفاتيح

لكسر حالات التعادل، قارن حقلًا ثانيًا عندما يكون الحقل الأول متساويًا. يؤدي ذلك إلى الفرز حسب العمر، ثم حسب الاسم أبجديًا.

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

typedef struct { char name[16]; int age; } Person;

int cmp(const void *a, const void *b) {
    const Person *p = a, *q = b;
    if (p->age != q->age)
        return (p->age > q->age) - (p->age < q->age);
    return strcmp(p->name, q->name);
}

int main(void) {
    Person ppl[] = {{"Zoe", 30}, {"Amy", 30}, {"Bo", 25}};
    qsort(ppl, 3, sizeof(Person), cmp);
    for (int i = 0; i < 3; i++) printf("%d %s\n", ppl[i].age, ppl[i].name);
    return 0;
}

qsort غير مستقرة

لا يشترط معيار C أن تكون qsort مستقرة. إذا كنت تحتاج إلى الاستقرار، فأضف مفتاحًا لكسر التعادل، مثل الفهرس الأصلي، إلى دالة المقارنة.

الدالة المرافقة bsearch

تنفّذ bsearch بحثًا ثنائيًا في مصفوفة مرتبة باستخدام أسلوب دالة المقارنة نفسه. استخدمها مع qsort لإجراء عمليات بحث سريعة.

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

int cmp_int(const void *a, const void *b) {
    int x = *(const int *)a, y = *(const int *)b;
    return (x > y) - (x < y);
}

int main(void) {
    int a[] = {1, 3, 5, 7, 9};
    int key = 7;
    int *found = bsearch(&key, a, 5, sizeof(int), cmp_int);
    printf("%s\n", found ? "found" : "missing");
    return 0;
}

لماذا نستخدم qsort

إن qsort القياسية مختبرة جيدًا، وغالبًا ما تكون هجينة من introsort محسّنة، وتعمل مع أي نوع. لا تلجأ إلى خوارزمية فرز خاصة بك إلا عندما تحتاج إلى الاستقرار أو إلى سلوك خاص لا توفره المكتبة.

اختبار سريع

اختبر مدى فهمك للدالة qsort.

مراجعة

لقد تعلّمت استخدام دالة الفرز في المكتبة القياسية.

  • تفرز qsort(base, nmemb, size, compar) أي مصفوفة
  • تحوّل دوال المقارنة const void * وتعيد إشارة نتيجة المقارنة
  • تجنّب الطرح؛ واستخدم (x > y) - (x < y)
  • لا يضمن qsort الاستقرار؛ أما bsearch فهي الدالة المرافقة للبحث

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

هل درس «استخدام qsort» مجاني؟

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

ماذا ستتعلم في «استخدام qsort»؟

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

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

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

كم من الوقت يستغرق درس «استخدام qsort»؟

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

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

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

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

  1. ترتيبا الفقاعات والإدراج
  2. Quicksort
  3. Mergesort
  4. استخدام qsort
← العودة إلى C Academy