1.直接插入排序
1)手动排序举例
- 有序表初始从第一个元素(到第二趟为[5 64])
- 借助哨兵,后面的待插入元素从有序表末尾依次进行比较(将 7 插入有序表)
- 直到大于某一值(5)后,将该值下一个位置的值放到7的位置
- 将放在哨兵位置的待插入值(7)放到原来64的位置
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
第0趟 | (哨兵)5 | [ 64 ] | 5 | 7 | 89 | 6 | 24 |
第1趟 | 7 | [ 5 | 64 ] | 7 | 89 | 6 | 24 |
第2趟 | 89 | [ 5 | 7 | 64 ] | 89 | 6 | 24 |
第3趟 | 6 | [ 5 | 7 | 64 | 89 ] | 6 | 24 |
第4趟 | 24 | [ 5 | 6 | 7 | 64 | 89 ] | 24 |
第5趟 | [ 5 | 6 | 7 | 24 | 64 | 89 ] |
2)代码实现
for(int i = 2; i<A.length; i++){ // n次
r[0] = r[i]; // n-1次
j = i-1; // n-1次
while(r[0]<r[j]){
r[j+1] = r[j];
j = j-1;
}
r[j+1] = r[0]; // n-1次
}
3)效率分析
a.时间复杂度分析
如代码部分分析,其中未分析的4、5、6行复杂度可分别写为:
∑
i
=
2
n
t
j
\sum_{i=2}^{n}\ t_j
∑i=2n tj、
∑
i
=
2
n
(
t
j
−
1
)
\sum_{i=2}^{n}\ (t_j-1)
∑i=2n (tj−1)、
∑
i
=
2
n
(
t
j
−
1
)
\sum_{i=2}^{n}\ (t_j-1)
∑i=2n (tj−1)
最好情况为(顺序)while循环每次只执行一次,即
t
=
1
t = 1
t=1,时间复杂度为
5
n
−
2
5n-2
5n−2,即
O
(
n
)
O(n)
O(n)
最坏情况为(逆序)while循环每次执行i次,即t=i,时间复杂度为
n
2
+
(
2
+
n
)
(
n
−
1
)
/
2
+
3
n
+
3
n^2+(2+n)(n-1)/2+3n+3
n2+(2+n)(n−1)/2+3n+3,即
O
(
n
2
)
O(n^2)
O(n2)
平均时间复杂度也为
O
(
n
2
)
O(n^2)
O(n2)
b.空间复杂度分析
由于只应用到监视哨r[0],因此空间复杂度为 O ( 1 ) O(1) O(1)
c.稳定性
相等时不满足移动条件,因此,该排序算法为稳定性算法
2.折半插入排序
3.希尔排序
与折半插入排序都是直接插入排序的改进
设置增量,根据增量进行直接排序
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
16 | 25 | 12 | 30 | 47 | 11 | 23 | 36 | 09 | 18 | 31 | ||
d=5 | 11 | 23 | 12 | 09 | 18 | 16 | 25 | 36 | 30 | 47 | 31 | |
d=3 | 09 | 18 | 12 | 11 | 23 | 16 | 25 | 31 | 30 | 47 | 36 | |
d=1 | 09 | 11 | 12 | 16 | 18 | 23 | 25 | 30 | 31 | 36 | 47 |
复杂度是关于增量的函数,增量至今没有统一标准。
该方法只可得到局部复杂度结论,无法得到全局复杂度。
该方法不稳定。
如有错误望订正>_<