您的位置:首页 > 其它

排序算法之插入排序

2015-04-18 17:20 211 查看
插入算法的基本思想是:每次将一个待排序的记录,按照其关键字的大小插入到前面
已经排好序的子表中的合适位置,直到全部记录插入完成位置,下面介绍一下直接插
入排序、二分插入排序及希尔排序。
直接插入排序:设待排序的记录存放在数组R[0..n-1]中,排序过程的某一中间时刻,
R被分成两个子区间R[0..i-1]和R[i..n-1],前一个是已经排好顺序的有序区,后面
是无序区。直接插入排序的基本操作是将当前无序区的第一个记录R[i]插入到有序
区  R[0..i-1]的合适位置,使R[0..i]变为新的有序区。代码如下:


public class ZhiJieSort {
public static void main(String args[]){
int i ;
int a[] = {2,1,5,6,8,4,3};
insertSort(a, a.length);
System.out.println("排序后:");
for( i=0;i<a.length;i++){
System.out.print(a[i]+"  ");
}
}
public static void insertSort(int a[],int n){
int i,j,temp;
for(i=1;i<n;i++){
temp=a[i];
j=i-1;       //从右向左在有序去a[0..i-1]中找到a[i]的插入位置
while(j>=0 && temp<a[j]){
a[j+1] = a[j]; //将记录大于a[i]的记录右移
j--;
}
a[j+1] = temp; //在j+1处插入a[i]
}

}

}


表出态是正序的时候时间复杂度最小O(n),表初态为反序时,时间复杂度最大O(n2),
直接插入排序中只用到了i,j,temp三个辅助变量,与问题规模无关,所以空间复杂度
是O(1),直接插入排序是稳定的排序方法 。
二分插入排序:由于插入排序是在有序子表中进行查找和插入的,查找方法可以使用
二分查找来提高查找效率。仅查找记录位置的方法不同,其余跟直接插入思想一致。
代码如下:


public class ErFenSort {
public static void main(String[] args){
int i;
int a[] = {2,8,6,1,4,5,9};
insertSort(a, a.length);
for(i=0;i<a.length;i++){
System.out.print(a[i]+"  ");
}
}
public static void insertSort(int a[],int n){
int i,j,low,mid,high,temp;
for(i=1;i<n;i++){
temp=a[i]; //将a[i]存入temp
low = 0;
high = i-1;
while(low<=high){  //在a[low..high]中用二分查找插入的位置
mid = (low+high)/2;  //取中间位置
if(temp<a[mid]){
high = mid-1;   //插入点在左半边
} else{
low  = mid+1;  //插入点在右半边
}
}
for(j=i-1;j>=high+1;j--){  //记录后移
a[j+1]= a[j];
}
a[high+1] = temp;    //插入
}
}
}


二分插入排序的空间复杂度为O(1),二分插入排序只是减少了关键字的比较次数,
记录的移动次数并没有改变,因此时间复杂度仍为O(n2)。
希尔排序:实际是一种分组插入方法,基本思想是先取一个小于n的整数d1作为第
一个增量,把表的全部记录分成d1组,所有距离为d1的倍数的被分在同一组,在
各组内进行直接插入排序;然后取第二个增量d2(<d1)重复上面的分组和排序,
直至增量为1,即所有记录放在同一组中进行直接插入排序为止。代码如下:


public class ShellInsert {

public static void main(String[] args){
int a[] = {2,4,3,6,7,9,1,8};
shellInsert(a, a.length);
for(int i =0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void shellInsert(int a[],int n){
int i,j,gap,temp;
gap = n/2; //增量初值
while(gap>0){
for(i =gap;i<n;i++){ //对所有相差gap位置的所有元素组采用直接插入排序
temp = a[i];
j = i-gap;
while(j>=0 && temp<a[j]){ //对相隔gap位置的元素组进行排序
a[j+gap]=a[j];
j = j-gap;
}
a[j+gap] = temp;
}
gap = gap/2;  //减小增量
}
}

}


希尔排序是不稳定的排序算法,时间复杂度为O(n1.3),空间复杂度为O(1),
通常情况下速度比直接插入排序快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息