直接插入排序
督促自己学习总结,特用文章的形式记录下来,共同进步
1.直接插入排序定义
待排序的数组分为三块,已排序列,正在排序位置,无序序列
有序序列 R[0,i-1] | R[i] | 无序序列[i+1,n] |
---|
需要将元素R[i]插入到有序子序列R[0,i-1]中,需要以下几步:
- 在R[0,i-1]找到R[i]的位置k
- 将k -> i-1的位置上的所有元素向后移动一位
- 把R[k] = R[i]
- 重复上述流程直到i=n-1
2.直接插入排序流程
排序初始
待排序序列为【212 854 399 135 649 450 67 503 441 598 】
红色为有序序列,绿色表示正在插入的元素
第一个默认为有序的序列,所以排序直接从i=1开始
第一趟,i = 1从R[1]=854开始
此时已经是最大值,不要移动
第二趟, i = 2 tmp = R[2] = 399
j = 1 399 < 854 854后移
j = 0 399 > 212 不移动, R[j+1] = tmp
至此第二遍遍历结束,前三个已经排列好
第三趟 i = 3 tmp = R[3] = 135
j = 2 135 < 954 854 后移
j=1 135 < 399 399 后移
j = 0 135 < 212 212后移
j = -1 j<0 移动结束 R[j+1] = tmp
第四趟 i = 4 tmp = R[4] = 649
j = i-1;j>=0;j-- j = 3 649 < 854 854 后移
j = i-1;j>=0;j-- j = 2 649 > 399 移动结束 退出循环 R[j+1] = R[3] = tmp = 649
第五躺 i = 5 tmp = R[5] = 450
初始状态:
j = i-1;j>=0;j-- j = 4 tmp < R[j] 成立 R[j] = 854 后移
j = i-1;j>=0;j-- j = 3 tmp < R[j] 成立 R[j] = 649 后移
j = i-1;j>=0;j-- j = 2 tmp < R[j] 不成立 移动结束 R[j+1] = tmp
第六趟 i = 6 tmp = R[6] = 67
初始状态:
移动结束时:
第七躺:
移动开始时:
移动结束时:
第八躺:
移动开始时:
移动结束时:
第九躺 = n-1(结束):
移动开始时:
移动结束时:
最终:
3.总结
稳定性
由于每次插入元素时,总时从后面先比较再发生移动,不会出现相同元素相对位置发生变化的情况,所以是稳定的排序算法
空间复杂度
只用了常数个辅助单元为O(1)
时间复杂度
1.排序趟数
排序趟数=n-1 跟数据是否有序无关
2.比较次数和移动次数
最好情况下数组已经有序,每一趟排序时比较一次,不发生移动
最坏的情况下数组已经逆序有序,每一趟排序时,比较i-1次,移动i次
所以平均时间复杂度时O(n`2)