Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Comparator Function ของ qsort() ใน C: เรียงลำดับข้อมูลโครงสร้าง


qsort() ใน <stdlib.h> ใช้ Quick Sort ต้องการ Comparator Function เพื่อกำหนดลำดับการเรียง ฟังก์ชันนี้รับ Pointer 2 ตัว (const void*) คืนค่า int บอกลำดับ

Signature ของ Comparator

int comparator(const void* p1, const void* p2);

ค่าคืนและความหมาย

Return Valueความหมาย
< 0Element p1 อยู่ก่อน p2
== 0Element เท่ากัน
> 0Element p1 อยู่หลัง p2

Pattern มาตรฐานสำหรับ Numeric Types

// Ascending (น้อยไปมาก)
int cmp_int(const void* a, const void* b) {
    int ia = *(const int*)a;
    int ib = *(const int*)b;
    return (ia > ib) - (ia < ib); // Safe: ไม่ Overflow
}

// Descending (มากไปน้อย)
int cmp_int_desc(const void* a, const void* b) {
    return *(const int*)b - *(const int*)a;
}

ตัวอย่าง: เรียง Struct Book ตามราคา

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

typedef struct {
    char title[50];
    int pages;
    float price;
} Book;

// Comparator: เรียงตาม Price Ascending
int compareBook(const void* a, const void* b) {
    const Book* b1 = (const Book*)a;
    const Book* b2 = (const Book*)b;
    
    // วิธีปลอดภัยสำหรับ Float (หลีกเลี่ยง Precision Issue)
    if (b1->price < b2->price) return -1;
    if (b1->price > b2->price) return 1;
    return 0;
}

int main() {
    Book books[5] = {
        {"C Programming", 260, 450.0f},
        {"DBMS Guide", 850, 775.0f},
        {"Learn C++", 350, 520.0f},
        {"Data Structures", 380, 430.0f},
        {"Learn Python", 500, 300.0f}
    };
    
    // qsort(array, count, size, comparator)
    qsort(books, 5, sizeof(Book), compareBook);
    
    printf("%-20s %5s %10s\n", "Title", "Pages", "Price");
    for (int i = 0; i < 5; i++) {
        printf("%-20s %5d %10.2f\n", books[i].title, books[i].pages, books[i].price);
    }
    return 0;
}

ผลลัพธ์

Title                   Pages     Price
Learn Python              500    300.00
Data Structures           380    430.00
C Programming             260    450.00
Learn C++                 350    520.00
DBMS Guide                850    775.00

Comparator สำหรับ String

int cmp_string(const void* a, const void* b) {
    const char* sa = *(const char**)a; // Array of char*
    const char* sb = *(const char**)b;
    return strcmp(sa, sb);
}

// ใช้กับ char* arr[]
char* names[] = {"Charlie", "Alice", "Bob"};
qsort(names, 3, sizeof(char*), cmp_string);

ข้อผิดพลาดทั่วไป

  • Cast ผิด: ต้อง Cast เป็น const Type* ก่อน Dereference
  • Integer Overflow: return a - b อาจ Overflow → ใช้ (a>b)-(a
  • Float Comparison: อย่าใช้ return a - b กับ Float ใช้ if-else
  • Const Correctness: Parameter ต้องเป็น const void*

C++ Alternative: std::sort

ใน C++ ควรใช้ std::sort พร้อม Lambda/Function Object เร็วกว่าและ Type-Safe

#include <algorithm>
#include <vector>

std::vector books = {...};
std::sort(books.begin(), books.end(), 
    [](const Book& a, const Book& b) { return a.price < b.price; });