排序可以说是相当常用的一类数据处理方式,而进行排序的方法也是多种多样的,此文主要记录经典的排序算法,并阐明基本原理
开始之前
- 所有的排序算法以函数形式展现,采用C语言编写
- 函数风格统一,命名规则同
ASort
,A为排序方法名称,首字母大写,传参均仅传入数组及其大小,函数类型为void
,即直接将原数组进行排序 - 所有排序的终点,也就时排序后的结果,为从大到小排序
为了让排序更好的进行,首先编写交换函数,即Swap()
函数
代码:
1 |
|
冒泡排序
冒泡排序可谓是相当经典的一个排序算法,记得自己大一面试学校社团之时,学长让第一个去了解的排序算法就是冒泡算法
实现思路
- 冒泡,顾名思义,就是将需排序的元素,看作大小不同的泡泡进行处理
- 首先将数组进行一趟从头至尾的扫描,遇到后者比前者大的元素,就将二者交换,一趟扫描之后,最大的元素实现沉底
- 那么只需要扫描n趟,就可让数组排列整齐
结合上述思路,我们可以写出以下代码:
代码1
1 | void BubbleSort (ELEMENT_TYPE a[], int n) { // 冒泡 |
- 上述代码相当简单,但是还可进行优化
- 因为冒泡排序过程中,有可能只进行小于n趟就已经排序完成,之后的扫描都属于无用功,所以加一标记,使其在扫描一趟的过程中,若无元素交换,则直接结束循环
代码2
1 | void BubbleSort (ELEMENT_TYPE a[], int n) { // 冒泡 |
如此一来,其最好情况为O(N)
,而最坏情况为O(N^2)
插入排序
插入排序也是简单排序的一种,也是比较常见的一种算法
实现思路
- 为了更好地理解插入算法,我们引入打牌时的实例
- 打牌时,为方便出牌,我们一般将牌有顺序地拿着,当摸一张牌时,我们会与手中已排序完成的牌进行比较,以插入到合适的位置
- 插入排序也是模拟了这一过程,首先假设数组中的首个元素已经 “拿在手中” ,之后将数组中的元素依次取出,进行插入
代码
1 | void InsertionSort(ELEMENT_TYPE a[], int n) { // 插入 |
- 代码在插入的时候是从后往前比较的,也就是从
i
到0
- 插入排序无需进行数字的交换,某种程度来说代码量是少于冒泡的
- 其最好情况为
O(N)
,而最坏情况为O(N^2)
选择排序
提到简单排序,就不得不说选择排序
实现思路
- 选择排序很好理解,就是首先遍历一遍数组,找到,该数组中最小的元素,与数组首位元素进行交换
- 这种交换需要进行
n
次,所以遍历也会进行n
次
代码
1 | void SelectionSort (ELEMENT_TYPE a[], int n) { // 选择 |
- 选择排序的时间复杂度是恒定的,无所谓最好最坏,均为
O(N^2)