一、排序简介
在编程中,排序是一个非常常见的操作, 排序的各种算法也曾困扰着我们,冒泡排序、插入排序、选序、归并排序等,再深入了解 'qsort' 函数之前,我先简要介绍几种常见的排序算法:
1.冒泡排序:通过多次遍历数组,依次比较相邻的元素,并将较大的元素逐渐“冒泡”到数组末尾。时间复杂度为 O(n^2)。
2.插入排序:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。时间复杂度为 O(n^2)。
3.选择排序:在未排序序列中找到最小(最大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(最大)元素。时间复杂度为 O(n^2)。
4.快速排序:通过选择一个“基准”元素,将数组分成两部分,使得左边部分都小于基准,右边部分都大于基准,然后递归地对两部分进行排序。平均时间复杂度为 O(n log n)
二、 'qsort'函数简介
qsort
函数基于快速排序算法实现,具有高效、通用的特点,适用于各种数据类型的排序需求,qsort
函数的原型定义在 <stdlib.h>
头文件中:
参数解释:
base
:指向待排序数组的起始地址。num
:数组中的元素个数。size
:每个元素的大小(以字节为单位)。compar
:指向比较函数的指针,用于确定两个元素的相对顺序。
比较函数:
比较函数是 qsort
的关键,它决定了排序的顺序。比较函数的格式如下:
- p1 和 p2:指向数组中待比较的两个元素。
- 返回值:
- 小于 0:p1所指向元素会排在p2所指元素左边(也就是p1会排在p2前面);
- 等于 0:p1所指元素与p2所指元素顺序不确定;
- 大于 0:p1所指向元素会排在p2所指元素右边(也就是p1会排在p2后面);
三、示例
这里我们以leetcode中的一道题为例,当然题有很多中解法,为了介绍 qsort 函数,我们就用 qsort 函数来写 。(原题请戳传送门)
- 按照奇偶顺序排列数组
- 由于题目要求返回一个数组,所以这里需要申请一片内存空间(14 line);
- 将内存拷贝到申请到的数组中(19 line);
- 按照偶数在前,奇数在后的顺序进行排列,主要看cam比较函数;
- 排序后数组的大小(21 line);
四、注意事项和性能考虑
- 比较函数的正确性:只要你能够提供一个比较函数,
qsort
就能够对数组中的元素进行排序。因此,理论上你可以用qsort
实现任何类型的排序,只需确保比较函数能够正确地比较数组中的元素,注意确保比较函数能够正确比较数组中的元素,否则排序结果将不可预期。 - 稳定性:
qsort
并不保证稳定排序(即相等元素的相对位置不变)。如果需要稳定排序,可能需要考虑其他算法。 - 性能:
qsort
基于快速排序,平均时间复杂度为 O(n log n),但最坏情况下为 O(n^2)。在某些特殊情况下,可以选择其他性能更优的排序算法。
结语
qsort
是 C 语言中一个非常实用的排序函数,通过定义合适的比较函数,可以对各种类型的数据进行高效排序。希望本文能帮助你理解并使用 qsort
函数,提高代码的效率和可维护性。