C语言数组怎么排序?三种常用算法与实现详解

来源:IOS教程作者:小黄人头衔:程序员
导读:本期聚焦于小黄人创作的《C语言数组怎么排序?三种常用算法与实现详解》,敬请观看详情。把一个无序的整型数组排好序,是刚接触C语言时必然要面对的基础操作。不同排序思路在时间复杂度和代码可读性上差别明显。冒泡排序靠相邻元素反复交换把大值逐步往后挪,逻辑直观但效率偏低;选择排序每轮挑出最小元素放到前面,交换次数少于冒泡;快速排序用分治思想把数组拆成小块处理,数据量大时速度优势突出。实际写代码时要根据数据规模选择合适的做法,并留意数组越界和比较函数写法。下面直接给出可运行的示例与原理说明,帮你把课本上的概念变成能编译通过的程序。

在C语言里,数组排序指的是将一段连续存储的同类型数据按照从小到大或从大到小的规则重新排列。由于C语言不提供内置的排序函数供初学者直接使用(标准库的qsort需要理解函数指针),手写排序算法既是练习数组操作和循环控制的好机会,也能让人看清不同算法在交换次数和比较次数上的真实差距。理解这些基础算法,对后续学习结构体和文件数据整理都有直接帮助。

C语言数组怎么排序?三种常用算法与实现详解

冒泡排序的实现与细节分析

冒泡排序的核心思想是:从数组第一个元素开始,依次比较相邻的两个元素,如果前面的数比后面的大就交换位置。这样一轮下来,最大的数就会像气泡一样“浮”到数组末尾。接着对前面的元素重复同样的过程,直到所有元素都有序。这种写法最容易被理解,因此常常作为教学示例出现。

在代码层面,我们需要两层循环。外层循环控制已经排好多少个大数,内层循环负责在尚未排好的区间内做相邻比较。一个常见的优化是,如果某一轮内没有发生任何交换,说明数组已经有序,可以提前结束。下面给出带提前退出优化的冒泡排序代码:

#include <stdio.h>

void bubble_sort(int arr[], int n) {
    int i, j, temp;
    int swapped;
    for (i = 0; i < n - 1; i++) {
        swapped = 0;
        for (j = 0; j < n - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                swapped = 1;
            }
        }
        if (swapped == 0) {
            break;
        }
    }
}

int main() {
    int data[] = {5, 2, 9, 1, 3};
    int size = sizeof(data) / sizeof(data[0]);
    bubble_sort(data, size);
    for (int k = 0; k < size; k++) {
        printf("%d ", data[k]);
    }
    return 0;
}

冒泡排序的时间复杂度在最坏和平均情况下都是 O(n^2),当数据量超过几千时就会明显变慢。它的优点是稳定(相等元素不改变原有相对顺序),并且代码非常短,调试方便。缺点也很突出:不必要的交换和比较太多。如果在面试或作业中只要求“能排就行”,冒泡可以胜任;但在真实项目里处理大规模数据一般不会选它。

选择排序与快速排序的对比实践

选择排序的思路和冒泡不同:它每一轮都在未排序区间中找到最小(或最大)的元素,然后直接和区间第一个位置交换。这样做把“频繁交换”变成了“每轮最多一次交换”,虽然比较次数还是 O(n^2),但数据移动次数降低了。下面的代码演示了升序选择排序:

#include <stdio.h>

void select_sort(int arr[], int n) {
    int i, j, min_idx, temp;
    for (i = 0; i < n - 1; i++) {
        min_idx = i;
        for (j = i + 1; j < n; j++) {
            if (arr[j] < arr[min_idx]) {
                min_idx = j;
            }
        }
        if (min_idx != i) {
            temp = arr[i];
            arr[i] = arr[min_idx];
            arr[min_idx] = temp;
        }
    }
}

int main() {
    int data[] = {4, 6, 2, 8, 1};
    int size = sizeof(data) / sizeof(data[0]);
    select_sort(data, size);
    for (int k = 0; k < size; k++) {
        printf("%d ", data[k]);
    }
    return 0;
}

快速排序则是另一套逻辑:选一个基准值,把比它小的放左边、比它大的放右边,再对左右两部分递归处理。它的平均时间复杂度是 O(n log n),适合大数据量。下面给出一个简单的递归快排示例:

#include <stdio.h>

void quick_sort(int arr[], int left, int right) {
    if (left >= right) return;
    int pivot = arr[left];
    int i = left, j = right;
    int temp;
    while (i < j) {
        while (i < j && arr[j] >= pivot) j--;
        while (i < j && arr[i] <= pivot) i++;
        if (i < j) {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    arr[left] = arr[i];
    arr[i] = pivot;
    quick_sort(arr, left, i - 1);
    quick_sort(arr, i + 1, right);
}

int main() {
    int data[] = {7, 3, 9, 2, 5};
    int size = sizeof(data) / sizeof(data[0]);
    quick_sort(data, 0, size - 1);
    for (int k = 0; k < size; k++) {
        printf("%d ", data[k]);
    }
    return 0;
}

从实践角度看,选择排序代码比快排好写,也不易出递归栈溢出问题,但效率依旧不高。快排写错边界条件就容易死循环或越界,比如上面代码中left >= right的退出判断就不能少。若数组已经接近有序,快排可能退化成 O(n^2),这时可随机选基准来缓解。对于普通学习者,先写对冒泡和选择,再挑战快排是比较稳的路线。

用标准库qsort处理数组排序

除了自己写算法,C语言标准库提供了qsort函数,声明在stdlib.h里。它基于快速排序的变体实现,通过函数指针让用户自定义比较规则,因此可以排序任意类型的数组,包括结构体数组。掌握qsort能省掉大量重复代码,也是理解回调函数的入门练习。

使用qsort时必须写一个比较函数,其原型为int cmp(const void *a, const void *b)。函数返回负值表示 a 应排在 b 前,返回零表示相等,返回正值表示 a 应排在 b 后。对整型数组来说,先把指针转成int *再相减即可。示例代码如下:

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

int cmp(const void *a, const void *b) {
    return (*(int *)a - *(int *)b);
}

int main() {
    int data[] = {10, 3, 8, 1, 6};
    int size = sizeof(data) / sizeof(data[0]);
    qsort(data, size, sizeof(int), cmp);
    for (int k = 0; k < size; k++) {
        printf("%d ", data[k]);
    }
    return 0;
}

使用qsort时要注意第三个参数sizeof(int)写错会导致内存读取错位,比较函数里若直接返回相减结果在数值极大时可能有溢出风险,更稳妥的写法是使用大于小于判断返回 1、0、-1。另外,qsort不保证相等元素的原有顺序,因此不属于稳定排序。当项目里需要排基础类型数组时,优先用qsort减少bug;当面试要求手撕算法时,再使用前面写的冒泡、选择或快排来展示逻辑。

C语言数组排序bubble_sort修改时间:2026-08-19 03:18:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。