排序算法01 - 插入排序 + SHELL排序(C语言)
直接插入排序
原理
将a[0]作为哨兵,从a[2]开始遍历数组,如果发现前者比后者大,则将后者存入哨兵,再从后向前调整数组元素的位置,最后将哨兵插入即可。

折半插入排序
原理
和直接插入挺像的,从a[2]遍历数组,不过折半不是和直接插入一样找哨兵,而是遍历的元素作为哨兵,在通过二分寻找之前有序数组中哨兵该插入的位置,之后和直接插入一样调整数组元素。
就是a1,a2有序后找a3插入位置,以此类推。
学了二分应该一听就懂吧(bushi
Shell排序

原理
就是插入排序的升级版(分治)
首先我们以数组长度的一半作为分割点(5),以上图为例就是[1,6],[2,7],[3,8],[4,9],[5,10]
对他们分别进行插入排序
然后再继续上述的一半作为分割点(2)得[1,3,5,7,9][2,4,6,8,10]
以此类推
代码
#include<stdio.h>
const int N=10010;
int a[N],n;
// 直接插入排序
void insert_sort(int a[])
{
int j;
for(int i=2;i<=n;i++)
{
if(a[i]<a[i-1]) {
a[0] = a[i];
for (j = i - 1; a[j] > a[0]; j--)
a[j + 1] = a[j];
a[j+1] = a[0];
}
}
}
// 折半插入排序
void half_insert_sort(int a[])
{
int l,r,mid;
for(int i=2;i<=n;i++)
{
int l=1,r=i-1;
a[0] = a[i];
while(l<=r){
mid = (l+r)>>1;
if(a[0]<a[mid]) r=mid-1;
else l=mid+1;
}
for(int j=i-1;j>=r+1;j--)
a[j+1] = a[j];
a[r+1] = a[0];
}
}
//Shell排序
void shell_sort(int a[])
{
int j;
for(int dk=n/2;dk>=1;dk=dk/2)
{
for(int i=dk+1;i<=n;i++)
if (a[i] < a[i - dk]) {
a[0] = a[i];
for (j = i - dk; a[j] > a[0] && j > 0; j -= dk)
a[j + dk] = a[j];
a[j + dk] = a[0];
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
insert_sort(a);
half_insert_sort(a);
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
return 0;
}

浙公网安备 33010602011771号