排序算法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;
}
posted @ 2024-03-18 11:54  zmhzmh  阅读(60)  评论(0)    收藏  举报