/*插入排序
* 思想: 就像整理扑克牌一样,一张一张的拿起来,将刚拿起来的牌插入到合适的位置。
* 具体的方法是,刚拿起来的一张牌和前一张牌比较,比它小就交换,然后往前一个比较,直到它比前一个大
* 这样一张张插入,直到最后一张插入合适位置后,整副牌就是有序的。
* 时间复杂度: 对于随机排列的长度为N且逐渐不重复的数组
* 最好情况: N-1次比较,0次交换 (本来就是排好序的)
* 平均情况: N²/4次比较,N²/4次交换
* 最坏情况: N²/2次比较,N²/2次交换
* 特点: 插入排序所需的时间 取决于 输入中元素的初始顺序。适用于对部分有序的数组进行排序。
*
* */
package paixu;
public class Insertion extends Example{
public static void sort(Comparable[] a){
int N = a.length;
for(int i=1; i<N; i++){
//将a[i]插入到a[i-1],a[i-2],a[i-3]...中
for(int j=i; j>0&&less(a[j],a[j-1]); j--){
exch(a,j,j-1);
}
}
}
public static void main(String[] args) {
Insertion insertion = new Insertion();
Integer[] a = {2,3,4,5,9,8,7,10};
insertion.sort(a);
Example.show(a);
System.out.println(Example.isSorted(a));
}
}
上述排序算法可以改进: 在内循环中将较大元素都向右移动,而不总是交换
/*插入排序(改进版本)
* 思想: 就像拿扑克牌一样,一张一张拿起来,插入到合适的位置
* 具体方法就是,将新拿到的一张牌,如果比前面一张小,就把前一张往后挪,
* 再和前面的比较,直到大于前面那张牌,就插入那个牌后面*/
package paixu;
public class Insertion extends Example{
public static void sort(Comparable[] a) {
int N = a.length;
for(int i=1; i<N; i++){
Comparable tmp = a[i];
int j;
for( j=i-1; j>=0; j--){
if( less(tmp, a[j]) ){
//如果比前面的小,就把前面的往后挪
a[j+1] = a[j];
}else{
//a[j+1] = tmp; //这句话不能放在这儿,
//因为tmp可能小于a[0],这样的话执行完内循环之后,tmp没有被放在合适的位置(即a[0]的值没有变)
break;
}
}
a[j+1] = tmp; //这句话必须放在这儿
}
}
public static void main(String[] args) {
Integer[] a = {4,5,6,1,2,3,9,8,7,123,-1,22};
Insertion.sort(a);
Insertion.show(a);
}
}