菜鸡笔记之——插入排序

菜鸡笔记之——插入排序

插入排序可分为:直接插入排序、折半插入排序
一、直接插入排序
时间复杂度为O(n^2)
思路(以从小到大排序为例):
1、给定一组数据,只看第一个元素,认为已经排好序;(一个数可以看成排 好序,这没的说)
2、看a[0]与a[1]的大小关系,并把a[1]赋给临时变量temp,如果a[0]大于a[1],将a[0]的值赋给a[1](相当于把a[0]往右挪一个位置),然后把temp插入到第一个位置,否则不动;
3、看第i个数与第前面已排序的各个数的大小关系,并把第i个数赋给临时变量temp,把比a[i]大的数都往后挪一个位置,然后把temp插入到空出来的位置;
4、重复3,直到遍历完整组数据

# include <stdio.h>
# include <malloc.h>

int main(void)
{
    int N,i,flag,temp;
    printf("the number of the list:");
    scanf("%d",&N);
    int * list = NULL;
    list = (int *)malloc(sizeof(int)*N);    //动态分配内存
    if (list==NULL)
    {
        printf("error!\n");
        exit(-1);
    }
    for (i = 0;i<N;i++)     //输入数据
    {
        scanf("%d",list+i);
    }
    //排序
    for (i = 1;i<N;i++)
    {
        temp = *(list+i);   //将当前数值记住
        flag = i-1;
        while ((flag>=0)&&(*(list+flag)>temp))      //从*(list+flag)开始,从右往左,把比temp
        {                                           //大的元素向右挪一位,直到*(list+flag)<=temp为止
            *(list+flag+1) = *(list+flag);
            flag--;
        }
        *(list+flag+1) = temp;      //将temp插入
    }
    for (i = 0;i<N;i++)     //输出已排序数据
    {
        printf("%3d",*(list+i));
    }
    free(list);

    return 0;
}

(👆用动态内存分配决定数组大小)

二、折半插入排序
时间复杂度为O(n^2)

思路:
插入排序分为直接插入与折半插入,折半插入与直接插入相比,只是在查找插入位置时方法优化了而已,直接插入在查找插入位置时是逐次比较,直到遇到第一个比他小(大)的数后插入,折半插入查找插入位置时类似于二分查找

# include <stdio.h>
# include <malloc.h>

int main(void)
{
    int N,i,j,key;
    printf("the number of the list:");
    scanf("%d",&N);
    int * list = NULL;
    list = (int *)malloc(sizeof(int)*N);
    if (list==NULL)
    {
        printf("error!\n");
        exit(-1);
    }
    //输入
    for (i = 0;i<N;i++)
    {
        scanf("%d",list+i);
    }
    //排序
    for (i = 1;i<N;i++)
    {
        int low = 0;
        int high = i-1;
        int mid;
        key = *(list+i);
        while (low<=high)       //折半查找插入位置
        {
            mid = (low+high)/2;
            if (*(list+mid)>key)
            {
                high = mid-1;
            }
            else
            {
                low = mid+1;
            }
        }
        for (j = i;j>low;j--)   //将插入位置到list+i-1位置上的数往后挪一格
        {
            *(list+j) = *(list+j-1);
        }
        *(list+low) = key;      //把*(list+i)填到空出来的位置
    }
    //输出
    for (i = 0;i<N;i++)
    {
        printf("%3d",*(list+i));
    }
    free(list);

    return 0;
}

(👆用动态内存分配决定数组大小)

        while (low<=high)       //折半查找插入位置
        {
            mid = (low+high)/2;
            if (*(list+mid)>key)
            {
                high = mid-1;
            }
            else
            {
                low = mid+1;
            }
        }

上面这一段最终想得到的是low的值(要插入的位置),比如
如果前面已排好序的一串数为:1,3 ,5,7,9
接下来的一个数(也就是key)的值为4,则low = 2,[key = 3时,low也是2,即插入的位置是遇到的第一个比key大/小的数的位置]。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值