C 语言排序算法全解析 + 实战案例:从原理到代码实现

108 阅读5分钟

排序是程序设计中最基础也最核心的算法场景之一,不同排序算法的时间复杂度、适用场景差异显著。本文将结合归并排序、快速排序、插入排序、选择排序、冒泡排序这 5 种经典排序算法的代码实现,拆解其核心逻辑,并附上一个趣味运算案例,帮助你彻底掌握排序算法的底层原理。

一、排序算法合集:代码 + 核心逻辑

以下是 5 种排序算法的完整实现与关键解析(基于用户输入的数组动态排序)。

屏幕截图 2025-12-28 101937.png

1.png

1. 归并排序:分治思想的经典实现

核心逻辑:将数组不断拆分为子数组,递归排序子数组后合并,是稳定的 O (nlogn) 复杂度算法。

c

运行

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

// 合并两个有序子数组
void merge(int a[], int left, int mid, int right) {
    int len1 = mid - left + 1;  // 左子数组长度
    int len2 = right - mid;     // 右子数组长度
    int *L = (int *)malloc(len1 * sizeof(int));
    int *R = (int *)malloc(len2 * sizeof(int));

    // 拷贝数据到临时数组
    for (int i = 0; i < len1; i++) L[i] = a[left + i];
    for (int j = 0; j < len2; j++) R[j] = a[mid + 1 + j];

    // 双指针合并
    int i = 0, j = 0, k = left;
    while (i < len1 && j < len2) {
        if (L[i] <= R[j]) a[k++] = L[i++];
        else a[k++] = R[j++];
    }
    // 处理剩余元素
    while (i < len1) a[k++] = L[i++];
    while (j < len2) a[k++] = R[j++];

    free(L);
    free(R);
}

// 归并排序递归函数
void mergesort(int a[], int left, int right) {
    if (left >= right) return;  // 子数组长度≤1时终止
    int mid = (left + right) / 2;
    mergesort(a, left, mid);     // 排序左子数组
    mergesort(a, mid + 1, right);// 排序右子数组
    merge(a, left, mid, right);  // 合并有序子数组
}

2. 快速排序:高效的分治排序(平均 O (nlogn))

核心逻辑:选基准值,将数组分为 “≤基准” 和 “≥基准” 两部分,递归排序子数组。

c

运行

void quicksort(int a[], int left, int right) {
    if (left >= right) return;
    int i = left, j = right;
    int pivot = a[i];  // 选左边界为基准

    while (i < j) {
        // 从右找第一个<基准的元素
        while (i < j && a[j] >= pivot) j--;
        a[i] = a[j];
        // 从左找第一个>基准的元素
        while (i < j && a[i] <= pivot) i++;
        a[j] = a[i];
    }
    a[i] = pivot;  // 基准归位
    quicksort(a, left, i - 1);  // 排序左子数组
    quicksort(a, i + 1, right); // 排序右子数组
}

3. 插入排序:适合小规模数据(O (n²))

核心逻辑:将元素逐个插入已排序区域的对应位置,类似整理扑克牌。

c

运行

void insertsort(int a[], int n) {
    int i, j, temp;
    // 遍历未排序区域
    for (i = 1; i < n; i++) {
        temp = a[i];  // 取出当前元素
        j = i - 1;
        // 已排序区域中比temp大的元素后移
        while (j >= 0 && a[j] > temp) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = temp;  // 插入到正确位置
    }
}

4. 选择排序:每次选最小元素交换(O (n²))

核心逻辑:遍历未排序区域,找到最小元素,与当前位置交换。

c

运行

// 交换函数
void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

void selectsort(int a[], int n) {
    int i, j, min;
    for (i = 0; i < n - 1; i++) {
        min = i;  // 假设当前位置是最小值
        // 找未排序区域的最小值下标
        for (j = i + 1; j < n; j++) {
            if (a[j] < a[min]) min = j;
        }
        swap(&a[i], &a[min]);  // 交换到当前位置
    }
}

5. 冒泡排序:相邻元素两两比较(O (n²))

核心逻辑:相邻元素逆序则交换,大元素逐步 “冒泡” 到尾部。

c

运行

void bubblesort(int a[], int n) {
    int i, j;
    for (i = 0; i < n; i++) {
        // 每轮将最大元素推到尾部,减少遍历次数
        for (j = 0; j < n - i - 1; j++) {
            if (a[j] > a[j + 1]) {
                swap(&a[j], &a[j + 1]);
            }
        }
    }
}

二、排序算法的统一调用示例

以下是 “用户输入数组→选择排序算法→输出结果” 的完整程序:

c

运行

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

// (此处需包含上述排序函数、swap函数)

int main() {
    int n;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n <= 0) {
        printf("错误:数组长度必须为正数!\n");
        return 1;
    }

    int a[n];
    printf("请输入数组元素(空格分隔):");
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    // 选择排序算法(以归并排序为例,可替换为其他排序函数)
    mergesort(a, 0, n - 1);

    printf("排序后的数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}

三、趣味运算案例:交替求和

除了排序,我们再看一个 C 语言运算案例:计算1 - 3 + 5 - 7 + ... + 99 - 101的结果。

c

运行

#include<stdio.h>
int main() {
    int i;
    int sum=0;
    int flag=1;  // 符号标记,1为正,-1为负
    for(i=1;i<102;i+=2) {  // 遍历1、3、5...101
        sum+=flag*i;
        flag=-flag;  // 符号交替
    }
    printf("%d\n", sum);  // 输出结果:-51
    return 0;
}

四、算法选型建议

算法时间复杂度(平均)稳定性适用场景
归并排序O(nlogn)稳定大规模数据、需要稳定排序
快速排序O(nlogn)不稳定大规模数据(效率最高)
插入排序O(n²)稳定小规模数据、基本有序数据
选择排序O(n²)不稳定数据量小、交换成本低的场景
冒泡排序O(n²)稳定教学演示(实际效率较低)

通过以上代码与解析,你可以快速掌握 5 种经典排序算法的实现与适用场景,同时理解 C 语言中数组操作、递归、循环的核心用法。可以将代码直接复制到编译器中运行,观察不同算法的排序效果哦!