直接插入排序
直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,基本操作是将一条记录直接插入到已经排好序的有序序列表中,从而得到一个新的、记录数量增加1的有序表。
算法思路
比如打牌时,发到手里的牌的顺序如下,选用插入法进行排序。
模拟手算
算法实现
- 不带哨兵实现
void InsertSort(int A[],int n){
int i,j,temp;
for ( i = 1; i < n; i++) { //将各元素插入已经排好序列中
if (A[i]<A[i-1]){ //若A[i]关键字小于前驱
temp = A[i]; //用temp暂存A[i]
for (j=i-1;j>=0 && A[j]>temp; --j) //检查所有前面已经排好序的元素
A[j+1]=A[j]; //所有大于temp的元素先后挪1位
A[j+1] = temp; //复制到插入位置
}
}
}
- 不带哨兵实现
void InsertSort_(int A[],int n){
int i,j;
for ( i = 2; i < n; i++) { //依次将A[2]~A[n]插入已经排好序列中
if (A[i]<A[i-1]){ //若A[i]关键字小于前驱,将A[i]插入有序表
A[0] = A[i]; //复制为哨兵,A[0]不存放元素
for (j=i-1; A[0]<A[j]; --j) //从后往前查找待插入位置
A[j+1]=A[j]; //向后挪位
A[j+1] = A[0]; //复制到插入位置
}
}
}
算法分析
① 时间复杂度分析: 对于整个排序过程需要执行n-1趟,
最好情况:正序,总的比较次数达最小值n-1,记录不需要移动
最坏情况:逆序,比较i次(依次同前面的i-1个记录进行比较,并且和哨兵比较1次),移动i+1次(前面的i-1个记录一次向后移动),最坏情况下,总的关键字比较次数KCN和记录移动次数RMN均达最大值,
若待排序序列中出现各种可能排列的概率相同,则可取上述最好情况和最坏情况的平均情况。 n2/4 。时间复杂度为O(n2)。 ②
空间复杂度 需要一个辅助空间r[0],空间复杂度为O(1)
算法特点
① 稳定排序
② 算法简单,且容易实现
③ 适用链式存储,单链表无序移动记录,修改指针即可。
④ 更适合初始记录==基本有序(正序)==的情况。
⑤ 初始记录 无序,n较大时间复杂度高,不宜采用
。