0Pricing
C Academy · บทเรียน

การใช้ qsort

การเรียงลำดับจากไลบรารีมาตรฐาน

การใช้ qsort เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การใช้ qsort”

การเรียงลำดับจากไลบรารีมาตรฐาน คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การใช้ qsort” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม

ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเรียงแบบฟองและแบบแทรก
  2. Quicksort
  3. Mergesort
  4. การใช้ qsort
← กลับไปที่ C Academy