插入排序
将元素插入到其他已经有序的元素序列中
的适当位置。
当前索引左边的所有元素都是有序的,为了给更小的元素腾出空间,它们可能会被移动。当索引到达数组的右端时,数组排序就完成了。
//插入排序,将a[]按升序排列
public void insertSort(int[] a){
if(a == null || a.length == 0) { //判断数组是否为空
System.out.println("该数组为空!");
return;
}
int len = a.length; //将数组的长度赋给len是为了防止每次for循环中判断时都调用length方法影响性能
for (int i = 1; i < len; i++) { //将a[i]插入到a[i-1]、a[i-2]...之中
int j = i;
while (j > 0 && a[j] < a[j - 1]) {
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
j--;
}
}
}
//改进1
//在内循环中将较大的元素都向右移动,而不总是交换两个元素。这样访问数组的次数就能减半
public void insertSort2(int[] a){
for (int i = 1; i < a.length; i++) {
int j = i;
int temp = a[j];
while (j > 0 && temp < a[j - 1]) {
a[j] = a[j - 1];
j--;
}
a[j] = temp;
}
}
对于长度为N的数组 (非改进插入排序算法),
平均情况下,插入排序需要大约
N2/4
N
2
/
4
次比较和
N2/4
N
2
/
4
次交换
最坏情况下,插入排序需要大约
N2/2
N
2
/
2
次比较和
N2/2
N
2
/
2
次交换
最好情况下,插入排序需要大约
N−1
N
−
1
次比较和
0
0
<script type="math/tex" id="MathJax-Element-6">0</script> 次交换
倒置
:数组中的两个顺序颠倒的元素
比如 EXAMPLE 中有11对倒置:EA、XA、XM、XP、XL、XE、ML、ME、PL、PE、LE
插入排序需要的交换
次数和数组中倒置的数量
相同
插入排序需要的比较
次数大于等于倒置的数量,小于等于倒置的数量加上数组的大小再减1
每次交换都改变了两个顺序颠倒的元素的位置,相当于减少了一对倒置,当倒置数量为 0 时,排序就完成了。
事实上,当倒置的数量的很少时,插入排序很可能比其他任何算法都要快。
插入排序的特点:
1、 运行时间与输入有关。插入排序所需的时间取决于输入中元素的初始顺序。如,对一个很大且其中的元素已经有序(或接近有序)的数组进行排序会比随机顺序或逆序数组要快的多