插入排序:直接插入排序&希尔排序
一、直接插入排序
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()));
}
}
从结果上看, 希尔排序的改进效果还是蛮明显的. 但是希尔排序并不是一个稳定的排序方式. 也就是说, 还是可能出现比快速排序慢的时候.
插入排序:直接插入排序&希尔排序的更多相关文章
- 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)
不多说,直接上干货! 插入排序包括直接插入排序.希尔排序. 1.直接插入排序: 如何写成代码: 首先设定插入次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不用 ...
- php六种基础算法:冒泡,选择,插入,快速,归并和希尔排序法
$arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序法 * 思路分析:法如其名,就是像冒泡一样,每次从数组当中 冒一个最大的数出来. * 比 ...
- Java实现希尔排序
华杰让我看了一道面试题:现有一段程序S,可以对任意n个数进行排序.如果现在需要对n^2个数进行排序,最少需要调用S多少次?(只允许调用S,不可以做别的操作). 看到了这 ...
- python算法之希尔排序
希尔排序 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出而得名. 希尔 ...
- [Swift]八大排序算法(六):希尔排序
排序分为内部排序和外部排序. 内部排序:是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 外部排序:指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存 ...
- python算法与数据结构-希尔排序算法(35)
一.希尔排序的介绍 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每 ...
- 排序--ShellSort 希尔排序
希尔排序 no 实现 希尔排序其实就是插入排序.只不过希尔排序在比较的元素的间隔不是1. 我们知道插入排序 都是 一个一个和之前的元素比较.发现比之前元素小就交换位置.但是希尔排序可能是和前第n个元素 ...
- "简单"的优化--希尔排序也没你想象中那么难
写在前边 大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦. 不过这篇文章呢,还是想跟大家聊一聊数据结构与算法,学校也是大二上才开设了数据结构这 ...
- 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)
本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...
- 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析之后续补充说明(有图有真相)
如果你觉得我的有些话有点唐突,你不理解可以想看看前一篇<C++之冒泡排序.希尔排序.快速排序.插入排序.堆排序.基数排序性能对比分析>. 这几天闲着没事就写了一篇<C++之冒泡排序. ...
随机推荐
- JAVA-部署-摘
一.下载 J2SDK下载http://java.sun.com/j2se/1.4.2/download.html 下载版本是j2sdk-1_4_2_08 ECLIPSE下载http://www.ec ...
- (最优m个候选人 和他们的编号)Jury Compromise (POJ 1015) 难
http://poj.org/problem?id=1015 Description In Frobnia, a far-away country, the verdicts in court t ...
- Eclipse怎么全局搜索和替换(整个项目)
我们用Eclipse编程,有时候需要将整个项目的某个字符串替换成其他的.那么我们该怎么操作呢?请接着往下看! 一,我们首先打开Eclipse,单击要替换字符串的项目 二,按下组合键:ctrl + H, ...
- 【Andorid开发框架学习】之Mina开发之Mina简介
今天我将介绍 Apache MINA的基本概念和 API,包括 I/O服务.I/O 会话.I/O 过滤器和 I/O 处理器. 一.MINA的简介 Apache MINA是一个网络应用程序框架,用来帮助 ...
- IOS绘图详解
http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/
- hdu 2838 Cow Sorting (树状数组+逆序对)
题目 题意:给你N个排列不规则的数,任务是把它从小到大排好,每次只能交换相邻两个数,交换一次的代价为两数之和,求最小代价 拿到这道题,我根本看不出这道题和树状数组有半毛钱关系,博客之,全说用树状数组做 ...
- hdu 5089 使做对k-1题最大概率的选题方案
http://acm.hdu.edu.cn/showproblem.php?pid=5089 给出N道难度递增的题目,难度用可能做出的百分比表示,选出K道题目使得做出K-1道题目的概率最大. 选k题的 ...
- Java学习--基本数据类型的定义和运算
例1: public class DataDemo05{ public static void main(String args[]){ char ch1 = '\"' ; // 表示的是一 ...
- Spring中ApplicationEvent和ApplicationListener封装
1.测试程序EventTest.java,发布一个事件只需要调用FrameEventHolder.publishEvent()方法即可. package com.junge.spring.event; ...
- .NET Entity Framework (with Oracle ODP.NET) -Code First
上一篇文章介绍了.NET Entity Framework ,并演示了Model First模式,本文将继续讨论 Code First 模式的实现. 一.摘要 1.目标 本文验证了通过Oracle D ...