插入排序
插入排序的基本操作就是“有序插入”,就是将元素注意插入到有序序列中,保持序列有序,从而使有序序列的长度不断增加。对数组a[n]排序时,起初a[0]被认为是长度为1的有序子序列。然后,按照有序插入法,i从1到n-1循环的将a[i]插入到有序序列中。在插入a[i]前,数组a的前半段(a[0]~a[i-1])是有序段,后半段(a[i]~a[n-1])是“无序段”。插入a[i]使a[0]~a[i]有序,也就要找到有序位置j(0<= j <=i),将a[i]插入到a[j]的位置上。
确定j的位置可以采用顺序法和二分法,分别对应直接插入排序和二分插入排序。
一、直接插入排序
1、 直接插入排序可用下面的例子说明
若待排序的数组a[]={2,4,3,1,7,5}
起始:
i=1;进行排序...243175
i=2;进行排序...234175
i=3;进行排序...234175→231475→213475→123475
i=4;进行排序...123475
i=5;进行排序...123475→123457
2、用JAVA语言描述该算法:public class zhijie_insertsort {
private int i,x,j;
public zhijie_insertsort(int a[],int n){
for (i=1;i<n;i++){ //准备插入a[i]
x=a[i]; //空出a[i]的位置
for(j=i-1;j>=0;j--){ //自右向左顺序查找有序位置
if(x<a[j]){
a[j+1]=a[j];
}
else
break;
}
a[j+1]=x; //将x插在位置j
}
}
}
附:空间复杂性S(n)=O(1);时间复杂性O(n^2)
二、二分插入排序
1、算法的实现:用二分查找方法为a[i]查找有序位置时,不能像直接插入那样,边比较边移动元素,只能在找到有序位置后将那些大于a[i]的元素一起右移。
2、算法实现过程:
二分插入排序:起始待排序数组为a[]={2,4,3,1,7,5}
i=1;x=4,left=0,right=i-1=0,mid=0→left=1;j=0;243175
i=2;x=3,left=0,right=1,mid=0→left=1→mid=1,right=1; j=1,left=1;234175
i=3;x=1,left=0,right=2,mid=1→right=1→right=0;j=2,left=0;123475
i=4;x=7,left=0,right=3,mid=1→left=1,mid=2→left=2,mid=2→left=3,mid=3→left=4;j=3,left=4;123475
i=5;x=5,left=0,right=4,mid=2→left=1,mid=2→left=2,mid=3→left=3,mid=3→left=4,mid=4→right=3;j=4,left=4;123457
3、用JAVA描述该算法:public class erfen_insertsort {
private int i,j,x,mid,left,right;
public erfen_insertsort(int a[],int n){
for(i=1;i<n;i++){
x=a[i];
left=0;
right=i-1;
while(left<=right){
mid=(left+right)/2;
if(x<a[mid])
right=mid-1;
left=mid+1;
}
for(j=i-1;j>=left;j--)
a[j+1]=a[j];
a[j+1]=x;
}
}
}
附:二分插入排序的空间复杂性S(n)=O(1);时间复杂性O(n^2)
参考书籍:高等教育出版社《数据结构与算法》