首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言排序練習:三數由大到小排序的多種實現與模板泛化思考

     編輯:關於C語言

問題描述

輸入三個整數 a, b, c,按從大到小順序輸出。原題提及「模板函數」但 C 語言無模板,實為普通函數。核心考點:交換排序邏輯、比較次數優化、泛型編程思想在 C 中的模擬。

原代碼:兩兩比較交換法

#include <stdio.h>

void sort(int l, int m, int n);

int main() {
    int a, b, c;
    printf("請輸入三個數: ");
    scanf("%d %d %d", &a, &b, &c);
    sort(a, b, c);
    return 0;
}

void sort(int l, int m, int n) {
    int t;
    if (l < m) { t = l; l = m; m = t; }  // 確保 l >= m
    if (l < n) { t = l; l = n; n = t; }  // 確保 l 為最大
    if (m < n) { t = m; m = n; n = t; }  // 確保 m >= n
    printf("排序後,由大到小: %d %d %d\n", l, m, n);
}

邏輯分析與優化

1. 比較網絡視角:最優比較次數 = 3

三元素排序的決策樹下界為 log₂(3!) ≈ 2.58 → 至少 3 次比較。原代碼恰好 3 次,屬於最優比較排序網絡。

2. 變量名改進

l, m, n 易混淆,建議用 a, b, c 或 x, y, z。

3. 宏實現交換(避免函數調用開銷)


#define SWAP(x, y) do { int tmp = x; x = y; y = tmp; } while(0)

void sort_macro(int a, int b, int c) {
    if (a < b) SWAP(a, b);
    if (a < c) SWAP(a, c);
    if (b < c) SWAP(b, c);
    printf("%d %d %d\n", a, b, c);
}

泛型排序在 C 中的三種模擬方案

方案一:函數指針 + void* (qsort 風格)


#include <stdlib.h>

int cmp_int_desc(const void *a, const void *b) {
    return (*(int*)b - *(int*)a);  // 降序
}

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

// 使用
int arr[3] = {a, b, c};
sort_generic(arr, 3, sizeof(int), cmp_int_desc);

方案二:宏生成類型專用函數


#define DEFINE_SORT(type, name) \
void name(type *a, type *b, type *c) { \
    type t; \
    if (*a < *b) { t = *a; *a = *b; *b = t; } \
    if (*a < *c) { t = *a; *a = *c; *c = t; } \
    if (*b < *c) { t = *b; *b = *c; *c = t; } \
}

DEFINE_SORT(int, sort_int)
DEFINE_SORT(float, sort_float)
DEFINE_SORT(double, sort_double)

方案三:_Generic (C11) 類型泛化


#define SORT3(a, b, c) _Generic((a), \
    int: sort3_int, \
    float: sort3_float, \
    double: sort3_double \
)(a, b, c)

擴展:N 元素排序的工程選擇

場景推薦方案複雜度
固定 3 元素比較網絡 (3次比較)O(1)
小規模 (n≤32)插入排序 / 網絡排序O(n²) 但常數小
通用大規模qsort (快排/混合排序)O(n log n)
近乎有序插入排序 / TimsortO(n)

總結

三數排序看似簡單,實則蘊含最優比較網絡、泛型編程模擬、C 語言類型系統限制等深層主題。關鍵收穫:

  • 固定小規模排序用比較網絡最優(無分支預測失敗、指令級並行友好);
  • C 無模板,但可用宏、函數指針、_Generic 實現泛化;
  • 宏 SWAP 需用 do{}while(0) 包裹防語法陷阱;
  • 實際項目中優先用標準庫 qsort,僅在極致性能敏感處手寫專用排序。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved