排序分类
- 插入排序
- 交换排序
- 选择排序
- 归并排序
- 基数排序
- 外部排序
排序的定义:将一组杂乱无章的数据按一定规律顺次排列起来
排序的目的:便于查找
排序算法的好坏如何衡量:
- 时间效率——排序速度(比较次数与移动次数)
- 空间效率——占内存辅助空间的大小
- 稳定性——A和B的关键字相等,排序后A、B的先后次序保持不变,则称这种排序算法是稳 定的。
记录序列采用顺序表存储(算法如下)
# define MAXSIZE 20 //设记录不超过20个
typedef int KeyType ; //设关键字为整型量(int型)
Typedef struct { //定义每个记录(数据元素)的结构
KeyType key ; //关键字
InfoType otherinfo; //其它数据项
}RedType ;
Typedef struct { //定义顺序表的结构
RedType r [ MAXSIZE +1 ]; //存储顺序表的向量
//r[0]一般作哨兵或缓冲区
int length ; //顺序表的长度
}SqList ;
插入排序:
基本思想:每步将一个待排序的对象,按其关键字大小,插入到前面已经排好序的一组对象的适当
位置上,直到对象全部插入为止。
内容:
直接插入排序(基于顺序查找)
折半插入查找(基于折半查找)
希尔排序(基于逐趟 缩小增量)
排序过程:
整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序。
算法步骤:
在R[1..i-1]中查找R[i]的插入位置,
R[i-1].key <= R[i].key结束
否则
1.将R[i]放入到监视哨,让R[i-1]后移;
2.将从i-2处开始判断如果大于插入记录,则后移
3.将监视哨上记录 插入到适当位置上。
算法描述
void InsertSort(SqList &L)
{
int i,j;
for(i=2;i<=L.length;++i)
if( L.r[i].key<L.r[i-1].key)//将L.r[i]插入有序子表
{
L.r[0]=L.r[i]; // 复制为哨兵
L.r[i]=L.r[i-1];
for(j=i-2; L.r[0].key<L.r[j].key;--j)
L.r[j+1]=L.r[j]; // 记录后移
L.r[j+1]=L.r[0]; //插入到正确位置
}
}
算法分析:
设对象个数为n,则执行n-1趟
比较次数和移动次数与初始排列有关
最好情况
最好情况下: 每趟只需比较 1 次,不移动
总比较次数为 n-1
最坏情况
第 i 趟比较i次,移动i+1次
直接插入排序的排序性能
- 与初序有关 最好情况(有序)最坏情况(逆序)
- 时间复杂度 最好情况O(n),最坏情况O(n2), 平均情况O(n2)
- 辅助空间O(1)
- 是稳定的排序方法