如下为插入排序动画演示,最终获得从左至右,从小到大依次排列的数字。
1.第1轮比较:
从第2个元素开始与第1个元素进行比较,如果比第1个元素小,则调换顺序,否则位置不变;共进行了1次比较。
2.第2轮比较
从第3个元素开始与第2个元素进行比较,如果比第2个元素小,则与第2个元素调换顺序,否则位置不变;如果位置进行了调换,则接着从第2个元素开始,与第1个元素进行比较,如果比第1个元素小,则调换顺序,否则位置不变;最多进行了2次比较。需要注意的是,当前轮中进行比较的时候,后续的比较依赖于前面的比较,即当第从第3个元素开始与第2个元素进行比较时,若比第2个元素大,那么后续的比较并不会发生,即完全没有必要对2个元素开始与第1个元素进行比较。
。。。
第N轮比较:
从第N+1个元素开始与第N个元素进行比较,如果比第N个元素小,则与第N个元素调换顺序,否则位置不变;如果位置进行了调换,则接着从第N个元素开始,与第N-1个元素进行比较,如果比第N-1个元素小,则调换顺序,否则位置不变;最多进行了N次比较。同理,当前轮中进行比较的时候,后续的比较依赖于前面的比较,任何一个元素比其左侧一个元素进行比较的时候,若比其大,那么后续的比较并不会发生,可以直接结束当前轮的比较。
总结:对N个数进行排序,经过了N-1轮比较。每轮比较中都是从右至左方向,相邻元素进行比较的。当进行到第N轮比较时,那么每次就从第N个位置的数字开始与左侧位置的元素进行比较,第1轮比较了1次,第N轮(N<length-1)最多比较了N次,最少比较了1次 。随着轮次N的增加,当前轮的比较次数期望值(1+N)/2在增加,是从右至左相邻进行比较。也就是说就比较次数而言,越来后来,可能越折腾。需要注意的是就某轮比较而言,后续比较依赖与前一次比较的结果,如果前此比较未互换位置,则后续比较可以不用进行,直接结束本轮比较,这可能是算法优化的方向。
最坏时间复杂度1+2+3........+n次比较,
即时间复杂度为o()
public class ChaRu {
public static void main(String[] args) {
int[] ints = {11,8 , 4 ,10, 3 , 6,9,7,1 , 5 , 12 , 72 , 23 , 13 , 0 , 2};
int length=ints.length;
//共进行了length - 1轮比较
for(int i=1;i<=length-1;i++){
//当前轮比较的次数为(length - i - 1)次,第1轮比较了1次,
// 第N轮(N<length-1)最多比较了N次,最少比较了1次
//随着轮次N的增加,当前轮的比较次数期望值(1+N)/2在增加,
// 是从右至左相邻进行比较。每轮比较,在左侧从第1到第N个
//位置的元素是从小到大依次排列的,与选择排序不同的是,即
// 第N个位置及其左侧数字并非是整个数组从小到大的顺序,其
// 相对位置虽然不会发生变化,但可能还会被插入后面新的元素,
// 因为第N+1到末尾的元素则还未参与比较,是无序的
for(int j=i;j>0;j--){
if(ints[j] < ints[j-1]){
int temp = ints[j-1];
ints[j-1] = ints[j];
ints[j] = temp;
}else{
break;
}
}
}
for (int a:ints
) {
System.out.println(a);
}
}
}