对直接插入排序的小小见解。

一.直接插入排序:
原理我就懒得解释了,网上和书上的原理很多很多,自己去看看就懂了,我就主要讲一下理解和代码。
据我的理解就是,把一个无序的数列插入到有序的数列中。设我们要排序的数列为array,数列中共有n个元素。
第一步:构建有序数列,其实这里的有序数列就是原来无序数列的第一个元素,但值得注意的是,第一个元素的下标是从1开始
问题:为什么要从0开始?
原来是把数组为0的元素拿来存放从无序数列取出来的元素,当然,从下标为2的元素开始取啦。
第二步:从无序数列中取元素存放在array[0]中,用array[0]查找有序数列,将其插入在合适的位置
第三步:重复第二步。
如图的过程。
再强调一下,写程序时array[0]不存放数列元素,存放从无序数列中取出来的元素。(注意是一直存放,存放完后再在有序数列里查找)
还有就是下标,从2开始取。这些都很容易出错,而我也是被这里坑了,所以一定要注意。
当然还很有必要分析时间复杂度,分析之前先看代码`,这是从小到大的排序。

#include <stdio.h>
#include <stdlib.h>

int n;

/*
 * 直接插入排序
 */
void InsertSort(int *array)
{
    int i, j;
    for (i = 2; i <= n; i++)
    {
        if (array[i] < array[i - 1])
        {
            array[0] = array[i];
            array[i] = array[i - 1];
            for (j = i - 2; array[0] < array[j]; j--)
            {
                array[j + 1] = array[j];
            }
            array[j + 1] = array[0];
        }
    }
}

int main()
{
    int i;
    int *array;
    printf("请输入数组的大小:");
    scanf("%d", &n);
    array = (int*) malloc(sizeof(int) * (n + 1));
    printf("请输入数据(用空格分隔):");
    for (i = 1; i <= n; i++)
    {
        scanf("%d", &array[i]);
    }
    InsertSort(array);
    printf("排序后为:");
    for (i = 1; i <= n; i++)
    {
        printf("%d ", array[i]);
    }
    printf("\n");
}

看完了程序就来看看时间复杂度吧,注意我这里分析的都是最坏时间复杂度。
其实我觉得时间复杂度就像高数找那个等价无穷小似的。要找最高阶
这里的最高阶无疑应该是那两个for循环
一般的双层循环其时间复杂度为m * n,但要理解其本质其实就是看内层循环里的那个语句执行了多少次,这样看就会更加简单了,并且也不会陷入疑惑,我刚开始就想把内层循环的各个m找到,然后加求和乘于n,但这样复杂度就变成了O(n^3),显然是忽略了什么,这样算其实把内层循环的次数算错了.
而知道本质就只需要知道内层里的那个语句执行了多少次就可以了,这样思路就清晰了 第一次 1次,第二次2次,当然按最坏的来计算。
加起来,自然复杂度应该是O(n^2)了。

还有就是知道这种排序方法的稳定性,我之前学的冒泡法就是稳定的排序方法,直接插入排序是稳定的,看程序就可以知道,比如遇到两个相等的,直接插入到后面就可以了。
二.希尔排序:
希尔排序是直接插入排序的一种改进:
但好像我还不怎么理解,该去刷Pat题哈哈,也就只能听下回分解了
感谢各位大佬指正错误,感激不尽
加油,不要放弃

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值