تابع qsort از کتابخانهی استاندارد(stdlib.h) از توابع مفید و البته استاندارد هست.این تابع با دادن آدرس آرایه، تعداد اعضا، اندازهی هر عضو و یک تابع برای مقایسهی دو عضو،آرایه را بصورت صعودی مرتب میکند.
با اینکه این تابع استاندارد هست اما اجباری در پیادهسازی آن نیست، به این معنی که qsort ضرورتا همهجا(منظور از همه جا دقیقا همهجاست! این یعنی ابررایانهها،فبلتها،رایانههای شخصی و همچنین میکروکنترلرها مانند AVR و PIC را نیز حساب میکنیم) وجود ندارد.
void qsort(void *base, size_t nmemb, size_t size, int (*compar(const void *, const void *)))
base یک اشارهگر بدون نوع به شروع آرایه است. nmemb تعداد اعضا و size نیز اندازهی هر عضو را مشخص میکند. پارامتر چهارم نیز یک تابع برای مقایسهی دو عضو هست که باید نتیجهی مشابه strcmp برگرداند. بعنی:
- اگر دو عضو با هم برابر بودند صفر برگرداند.
- اگر اولی کوچکتر از دومی بود، عددی منفی برگرداند.
- و اگر اولی بزرگتر از دومی بود، عددی مثبت برگرداند.
تابع بصورت پیشفرض آرایه را بصورت صعودی مرتب میکند، اگر میخواهید بصورت نزولی مرتب شود، کافیست تابع مقایسه برعکس کار کند.
#include <stdlib.h> #include <stdio.h> #define N 5 int cmp(const void *a, const void *b){ return *((int *)a) - *((int *)b); } main(){ int *numbers; numbers = (int *) calloc(N, sizeof(int)); for (int i = 0; i < N; i++) numbers[i] = rand(); for (int i = 0; i < N; i++) printf("%d\n", numbers[i]); puts(""); qsort(numbers, N, sizeof(int), cmp); for (int i = 0; i < N; i++) printf("%d\n", numbers[i]); }
فکر میکنم کد به اندازهی کافی گویا باشد! یک مثال دیگر که در آن از یک struct استفاده کردم و همچنین آرایه بصورت نزولی مرتب میشود:
#include <stdlib.h> #include <stdio.h> struct score_rec{ char name[3]; int8_t score; } highs[10]; int compare_func(const void *a, const void *b){ return ((struct score_rec *)b)->score - ((struct score_rec *)a)->score; } int main(){ int s; srand(s); for (int i = 0; i < 10; i++){ highs[i].name[0] = 65 + i; highs[i].name[1] = 0; highs[i].score = rand() % 101; } for (int i = 0; i < 10; i++){ printf("%s\t%d\n", highs[i].name, highs[i].score); } puts(""); qsort(&highs, 10,sizeof(struct score_rec), compare_func); for (int i = 0; i < 10; i++){ printf("%s\t%d\n", highs[i].name, highs[i].score); } }
توجه کنید که برای هستهی مولد اعداد شبه تصادفی(PRNG) از یک متغیر استفاده کردم که مقداردهی اولیه نشده است. این متغیر در زبان سی مقداری نامعلوم دارد.