八大排序
插入排序:
每次将一个待排序的记录,按其关键字大小插入到前边已经排好的记录集中,使记录仍然有序,直到所有待排序记录全部插入完成。
1.插入排序的思想
平均时间复杂度:O(n²)
空间复杂度:O(1)
稳定性:稳定√
假设待排序数据存放在数组 A[1…n]中,则 A[1]可看作是一个有序序列,让 i 从 2 开始,依次将 A[i]插入到有序
序列 A[1…i-1]中,A[n]插入完毕则整个过程结束,A[1…n]成为有序序列。
2.排序过程示例 (用【 】表示有序序列)
待排序数据: 【25】 54 8 54 21 1 97 2 73 15 (n=10)
i=2: 【25 54】 8 54 21 1 97 2 73 15
i=3: 【8 25 54】 54 21 1 97 2 73 15
i=4: 【8 25 54 54】 21 1 97 2 73 15
i=5: 【8 21 25 54 54】 1 97 2 73 15
i=6: 【1 8 21 25 54 54】 97 2 73 15
i=7: 【1 8 21 25 54 54 97】 2 73 15
i=8: 【1 2 8 21 25 54 54 97】 73 15
i=9: 【1 2 8 21 25 54 54 73 97】 15
i=10:【1 2 8 15 21 25 54 54 73 97】 排序结束
3.算法实现
可在数组中增加元素 A[0]作为关键值存储器和循环控制开关。第 i 趟排序,即 A[i]的插入过程为:
① 保存 A[i]→A[0]
② j = i −1
③ 如果 A[j]<=A[0](即待排序的 A[i]),则 A[0]→A[j+1],完成插入;
否则,将 A[j]后移一个位置:A[j]→A[j+1]; j = j −1;继续执行③
对于上面的数据实例,i 从 2 依次变化到 10 的过程中,j 值分别为{1,0,3,1,0,6,1,7,3}
4.程序代码
public class InsertSort {
public static void main(String[] args) {
print();
System.out.println();
insertSort();
print();
}
static int[] data = {25,54,8,54,21,1,97,2,73,15};
public static void insertSort(){
int tmp = 0, j=0;
for (int i = 1; i < data.length; i++) {
tmp = data[i];
j = i-1;
while(j>=0 && tmp < data[j]){
data[j+1] = data[j];
j--;
}
data[j+1] = tmp;
}
}
public static void print(){
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
}
}
25 54 8 54 21 1 97 2 73 15
1 2 8 15 21 25 54 54 73 97
5.算法分析
(1)稳定性:稳定
(2)时间复杂度:
①原始数据正序,总比较次数:n-1
②原始数据逆序,总比较次数:
∑
i
=
2
n
i
=
n
2
+
n
−
2
2
=
O
(
n
2
)
\sum_{i=2}^n i = \frac{n^2+n-2}{2} = O(n^2)
i=2∑ni=2n2+n−2=O(n2)
③原始数据无序,第 i 趟平均比较次数=
∑
j
=
1
i
j
/
i
=
i
+
1
2
\sum_{j=1}^i j/i = \frac{i+1}{2}
j=1∑ij/i=2i+1
总次数为:
n
2
+
3
n
4
=
O
(
n
2
)
\frac{n^2+3n}{4} = O(n^2)
4n2+3n=O(n2)
④可见,原始数据越趋向正序,比较次数和移动次数越少。
(3)空间复杂度:仅需一个单元 A[O]