1.直接插入排序:
边比较边移动,找到插入位置;
void InsertSort(ElemType A[],int n){
int i,j;
for(i=2;i<=n;i++){
//若A[i]小于前驱,需将A[i]插入有序表;
if(A[i].key<A[i-1].key){
A[0]=A[i]; //复制为哨兵,A[0]不存放元素;
for(j-i-1;A[0].key<A[j].key;j--)
A[j+1]=A[j];
A[j+1]=A[0]; //A[j]>=A[0],存放到A[j+1]
}
}
}
2.折半插入排序:
将比较和移动分离出来,先折半查找找出插入位置,再统一移动,最后插入;
void InsertSort(ElemType A[],int n){
int i,j,low,high,mid;
//将A[2]~A[n]依次插入到前面已排序序列
for(i=2;i<=n;i++){
//折半查找
A[0]=A[i];
low=1;high=i-1;
while(low<=high){
mid=(high+low)/2;
if(A[mid].key>A[0].key)
high=mid-1;
else
low=mid+1;
}
//统一后移之后插入
for(j=i-1;j>=high+1;j--)
A[j+1]=A[j];
A[high+1]=A[0];
}
}
3.希尔排序:
将待排序表分割成若干形如L[i,i+d,i+2d,…,i+kd]的子表,分别在组内进行插入排序,当表中元素呈’基本有序’,再对全体进行一次直接插入排序;
dk=n,则将表全部记录分成了n组;
dk=3:[1,4,7…],[2,5,8…],[3,6,9…];
void ShellSort(ElemType A[],int n){
//步长变化,最后一次dk=1,即全体的一次直接插入排序;
for(dk=n/2;dk>=1;dk=dk/2){
//在各组中进行直接插入排序;
//如对于组1A[1,1+dk,1+2*dk+...]进行排序:将A[1+dk]~A[1+n*dk]插入之前已经排好的序列;
//(i=dk+1;i<=n;++i):这里的i是在自己对应的组里排序,如对dk=3:i=2在组2,i=6在组3,i==n时也就排序结束了;
for(i=dk+1;i<=n;++i){
if(A[i].key<A[i-dk].key){
A[0]=A[i];
for(j=i-dk;j>0&&A[0].key<A[i].key;j-=dk)
A[j+dk]=A[j];
A[j+dk]=A[0];
}
}
}
}