一、直接插入排序

1. 思想

直接排序法, 可以分为两个部分, 一部分是有序的, 一部分是无序的.

从这个图上, 应该是能看清楚直接插入排序的思想了.

将无序部分的第一个与有序部分进行比较.

从有序部分的后面向前面比较, 然后不断地挪动有序部分的数据的位置

static void InsertSort(List<int> list)
{
   //从第二个数开始循环, 循环n-1次
for (int i = ; i < list.Count; i++)
{
     //将待排序的数拿出来, 以便后面挪位子
int temp = list[i];
     //j就是最后确定的那个最大/最小数的下标
int j = i;
while (j >= && temp < list[j - ])
{
       //将满足条件的数据向后移动一位, 腾空位, 为插入挪位子
list[j] = list[j - ];
j--;
}
list[j] = temp;
}
}

2. 复杂度

直接插入排序的最好情况下, 时间复杂度为O(n), 最坏情况下, 复杂度为O(n2);

证明见:

插入排序及其复杂度分析

3. 直接插入排序vs快速排序

从上面的代码来看, 直接插入排序需要不断地挪数据. 如果碰到连续整数, 那么挪动的数据就多了. 针对这种问题, 是否可以改进一下直接插入排序?

在比较的时候, 我是否可以跳着比较?

二、希尔排序

1. 思想

在比较的时候, 引入缩小增量比较的方式.

第一步. 使增量d=count/2, 将每隔d个数看成是一组无序的数, 然后对这组无序的数进行插入排序

第二步. 使增量d=d/2, 和第一步执行相同的操作, 一直到d=1的时候

代码:

static void ShellSort(List<int> list)
{
int step = list.Count / ;
while (step >= )
{
for (int i = step; i < list.Count; i++)
{
var temp = list[i];
int j = i;
while (j >= step && temp < list[j - step])
{
list[j] = list[j - step];
j -= step;
}
list[j] = temp;
}
step = step / ;
}
}

希尔排序与直接插入排序, 中间部分的代码基本一直, 不同的只是维度, 直接插入排序的维度是固定的1,

而希尔排序的维度是变化的. 从代码上看, 其实还是蛮简单的, 就拿着直接插入排序改吧改吧就成了.

2. 复杂度

希尔排序的时间复杂度, 和直接插入排序的最好&最坏时间复杂度居然是一样的, 同志们, 能相信么.

三、直接插入排序 vs 希尔排序

既然说希尔排序是直接插入排序的改进版, 那么他们究竟谁更厉害些呢? 会不会越改越差了?

static void Test()
{
//五次比较
for (int i = ; i <= ; i++)
{
List<int> list = new List<int>();
List<int> listA = new List<int>();
//插入2k个随机数到数组中
for (int j = ; j < ; j++)
{
Thread.Sleep();
list.Add(new Random((int)DateTime.Now.Ticks).Next(, ));
} listA.AddRange(list);
Console.WriteLine("\n第" + i + "次比较:{0}...", string.Join(",", list.Take())); Stopwatch watch = new Stopwatch();
watch.Start();
InsertSort(list);
watch.Stop();
Console.WriteLine("\n直接插入排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine("输出前是十个数:" + string.Join(",", list.Take().ToList())); watch.Restart();
ShellSort(listA);
watch.Stop();
Console.WriteLine("\n希尔排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine("输出前是十个数:" + string.Join(",", listA.Take().ToList()));
}
}

从结果上看, 希尔排序的改进效果还是蛮明显的. 但是希尔排序并不是一个稳定的排序方式. 也就是说, 还是可能出现比快速排序慢的时候.

插入排序:直接插入排序&希尔排序的更多相关文章

  1. 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)

    不多说,直接上干货! 插入排序包括直接插入排序.希尔排序. 1.直接插入排序: 如何写成代码: 首先设定插入次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不用 ...

  2. php六种基础算法:冒泡,选择,插入,快速,归并和希尔排序法

    $arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序法  *     思路分析:法如其名,就是像冒泡一样,每次从数组当中 冒一个最大的数出来.  *     比 ...

  3. Java实现希尔排序

            华杰让我看了一道面试题:现有一段程序S,可以对任意n个数进行排序.如果现在需要对n^2个数进行排序,最少需要调用S多少次?(只允许调用S,不可以做别的操作).         看到了这 ...

  4. python算法之希尔排序

    希尔排序 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出而得名. 希尔 ...

  5. [Swift]八大排序算法(六):希尔排序

    排序分为内部排序和外部排序. 内部排序:是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 外部排序:指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存 ...

  6. python算法与数据结构-希尔排序算法(35)

    一.希尔排序的介绍 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每 ...

  7. 排序--ShellSort 希尔排序

    希尔排序 no 实现 希尔排序其实就是插入排序.只不过希尔排序在比较的元素的间隔不是1. 我们知道插入排序 都是 一个一个和之前的元素比较.发现比之前元素小就交换位置.但是希尔排序可能是和前第n个元素 ...

  8. "简单"的优化--希尔排序也没你想象中那么难

    写在前边 大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦. 不过这篇文章呢,还是想跟大家聊一聊数据结构与算法,学校也是大二上才开设了数据结构这 ...

  9. 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)

    本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...

  10. 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析之后续补充说明(有图有真相)

    如果你觉得我的有些话有点唐突,你不理解可以想看看前一篇<C++之冒泡排序.希尔排序.快速排序.插入排序.堆排序.基数排序性能对比分析>. 这几天闲着没事就写了一篇<C++之冒泡排序. ...

随机推荐

  1. 20169207《Linux内核原理与分析》第三周作业

    这周主要对于以往的知识进行了复习,包括开始的Linux基础,以及对需要学习的新知识进行了复习,也对markdown的语法进行了初步的了解.开始学习markdown的一些基本语法和Linux的一些常用命 ...

  2. MySQL查询实例

    单表查询查询所有列 1 SELECT * FROM product; 查询指定列 1 SELECT pro_name,price,pinpai FROM product; 添加常量列 1 SELECT ...

  3. Codeforces Round #540 (Div. 3)--1118F1 - Tree Cutting (Easy Version)

    https://codeforces.com/contest/1118/problem/F1 #include<bits/stdc++.h> using namespace std; in ...

  4. 微软新一代Surface发布,参数曝光

    在沉寂许久之后,Surface 2及Surface Pro 2又有猛料爆出,这一次不单单是新品展示,伴随的还有更多的详细的参数和全新配件. 从外观来看,新一代的Surface外形上沿袭了上一代,但颜色 ...

  5. 第70讲:Scala界面GUI编程实战详解

    今天又学习了王家林老师的scala学习讲座第70讲,关于scala的界面编程,让我们来初步学习一下scala中界面编程的过程. 信息来源于 DT大数据梦工厂微信公众账号:DT_Spark 关注微信账号 ...

  6. Pychar-20170301快捷键

    Pychar IDE 2017.03.03 版本的特性 ------------------------------------------------Ctrl+D:(Dumplicated) 复制选 ...

  7. 《mysql必知必会》学习_第八章_20180730_欢

    第八章学习LIKE操作符,百分百(%)通配符,下划线(_)通配符 P47 select prod_id,prod_name from products where prod_name LIKE 'je ...

  8. codeforces877c

    C. Slava and tanks time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. javascript 减少全部变量

    方法1 自创建一个唯一的全局变量a,把自己用到的变量都加在a上 方法2:模块 String.method('test1', function(){ var a = '12'; return funct ...

  10. Python自动化开发 - 常用模块(一)

    本节内容 1.模块介绍 2.time&datetime模块 3.random模块 4.os模块 5.sys模块 6.json&pickle模块 7.logging模块 一.模块介绍 模 ...