目录
一、插入类排序
1、直接插入排序
1.1排序过程
1.2代码实现
#include <stdio.h>
void print(int data[], int n) //打印结果的函数
{
int i;
for (i = 0; i < n; i++)
{
printf("%d ", data[i]);
}
printf("\n");
}
void InsertSort(int A[],int n) {
int i, j, temp;
for (i = 1; i < n; i++) { //第一个数不用排,直接从第二个数开始
if (A[i] < A[i-1]) { //如果当前的元素小于前驱
temp = A[i]; //存入临时变量
}
for (j = i-1; j >= 0 && A[j] > temp; j--) {
A[j + 1] = A[j]; //右移
}
A[j + 1] = temp;
print(A,n);
}
}
int main() {
int A[5] = {5,4,3,2,1};
print(A, 5);
InsertSort(A, 5);
return 0;
}
2、二分插入排序
3、希尔插入排序
3.1 排序过程
3.2 代码实现
二、选择类排序
选择排序的基本方法是:每步从待排序记录中选出排序码最小的记录,顺序放在已排序的记录序列的后面,直到全部排完。
1、直接选择排序
1.1 概念
直接选择排序的方法是:首先在所有记录中选出排序码最小的记录,与第一个记录交换,然后在其余的记录中再选出排序码最小的记录与第二个记录交换,以此类推,直到全部排好序。
1.2 排序过程
1.3 算法实现
2、堆排序
2.1 概念
堆排序方法是先把待排序的记录构造成大根堆/小根堆,然后通过从堆中不断选出最大/最小元素,从而达到排序的目的。
方法就是不断的把堆的根节点与堆中序号最大的结点交换并取出来,剩下的结点重新建堆,递归进行。
2.2 建堆
以大根堆为例
2.3 排序过程
2.4 算法实现
2.5 例题
三、交换类排序
1、冒泡排序
1.1 排序过程
以冒大泡为例,两两比较,使较大的元素不断往后移动
【注】张乃孝版默认为冒大泡排序,也就是升序排列。
1.2 算法实现
注意设置一个标志位判断当前趟数是否存在交换,没有交换则排序完成,跳出循环。
2、快速排序
快速排序的基本思想是:在待排序的n个记录中任取一个记录作为枢轴元素(通常取第一个记录)为分区标准,把所有小于该排序码的记录移到左边,把所有大于该排序码的记录移到右边,中间放所选记录,称之为一趟排序;然后,对前后两个子序列分别重复上述过程。继续下去,直到所有记录都排好序。
2.1 排序过程
2.2 算法实现
2.3 快排小结
四、分配类排序
1、基数排序
1.1 排序过程
以两位数为例,只有十位和百位,两趟即可排好。
1.2 算法实现
1.3 基数排序小结
五、归并类排序
1、两路归并排序
设文件中有n个记录,可以看成n个子文件,每个子文件中只包含一个记录,先将每两个子文件归并,得到n/2个部分排序的较大的子文件,每个子文件包含2个记录;再将子文件归并,如此反复,直到得到一个文件。上述每步归并都是将两个子文件合成一个子文件,称为二路归并排序。
类似地还有三路归并排序或多路归并排序。
5.1 排序过程
5.2 算法实现
5.3 代价分析
六、综合比较
各种排序方法各有优缺点。排序算法之间的比较主要考虑以下几个方面:
(1)算法的时间复杂度与适应性
(2)算法的辅助空间与被排序对象的表示方式(3)排序算法的稳定性
(4) 算法结构的复杂性
(5)适合参加排序的数据的规模
1、时间复杂度&&空间复杂度&&算法稳定性&&适用场合
【注】“稳定” 与 “不稳定”?
若经过排序后,文件中排序码相等的记录之间的相对次序保持不变,则此排序算法是稳定的,否则为不稳定的。快速排序是不稳定的,因为在每次分区交换时,可能已经破坏了其他排序码相同的记录的顺序。
通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。