插入排序:直接插入排序希尔排序
一、直接插入排序
1. 思想
直接排序法, 可以分为两个部分, 一部分是有序的, 一部分是无序的.
从这个图上, 应该是能看清楚直接插入排序的思想了.
将无序部分的第一个与有序部分进行比较.
从有序部分的后面向前面比较, 然后不断地挪动有序部分的数据的位置
static void InsertSort(List<int> list) { //从第二个数开始循环, 循环n-1次for (int i = 1; i < list.Count; i++){ //将待排序的数拿出来, 以便后面挪位子int temp = list[i]; //j就是最后确定的那个最大/最小数的下标int j = i; while (j >= 1 && temp < list[j - 1]){ //将满足条件的数据向后移动一位, 腾空位, 为插入挪位子list[j] = list[j - 1];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 / 2;while (step >= 1){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 / 2;} }
希尔排序与直接插入排序, 中间部分的代码基本一直, 不同的只是维度, 直接插入排序的维度是固定的1,
而希尔排序的维度是变化的. 从代码上看, 其实还是蛮简单的, 就拿着直接插入排序改吧改吧就成了.
2. 复杂度
希尔排序的时间复杂度, 和直接插入排序的最好&最坏时间复杂度居然是一样的, 同志们, 能相信么.
三、直接插入排序 vs 希尔排序
既然说希尔排序是直接插入排序的改进版, 那么他们究竟谁更厉害些呢? 会不会越改越差了?
static void Test() {//五次比较for (int i = 1; i <= 5; i++){List<int> list = new List<int>();List<int> listA = new List<int>();//插入2k个随机数到数组中for (int j = 0; j < 10000; j++){Thread.Sleep(1);list.Add(new Random((int)DateTime.Now.Ticks).Next(0, 100000));}listA.AddRange(list);Console.WriteLine("\n第" + i + "次比较:{0}...", string.Join(",", list.Take(10)));Stopwatch watch = new Stopwatch();watch.Start();InsertSort(list);watch.Stop();Console.WriteLine("\n直接插入排序耗费时间:" + watch.ElapsedMilliseconds);Console.WriteLine("输出前是十个数:" + string.Join(",", list.Take(10).ToList()));watch.Restart();ShellSort(listA);watch.Stop();Console.WriteLine("\n希尔排序耗费时间:" + watch.ElapsedMilliseconds);Console.WriteLine("输出前是十个数:" + string.Join(",", listA.Take(10).ToList()));} }
从结果上看, 希尔排序的改进效果还是蛮明显的. 但是希尔排序并不是一个稳定的排序方式. 也就是说, 还是可能出现比快速排序慢的时候.
转载于:https://www.cnblogs.com/elvinle/p/6669258.html
插入排序:直接插入排序希尔排序相关推荐
- 插入排序(含希尔排序)的C/C++实现
直接插入排序 直接贴核心代码 for(i=1;i<n;i++)//n为数组长度{t=a[i];//取出待比较元素for(j=i-1;j>=0&&a[j]>t;j--) ...
- 排序之插入排序:直接插入+希尔排序
一.插入排序 1.思想:原理类似抓扑克牌,在有序表中进行插入和查找,插入合适的位置时,之后的元素需要往后移动 2.时间复杂度: 最好:O(N),正序情况,只有比较时间,无移动时间 最坏:O(N2),逆 ...
- 扑克牌式插入排序及升级版希尔排序
插入排序 问题提出:为什么叫做扑克牌式插入排序 这里我就得给大家解释一下,为什么我要叫做扑克牌式插入排序,很简单,小编本人喜欢打扑克牌...相信扑克牌大家应该都不会陌生,打扑克牌其实不仅仅是娱乐,同时 ...
- 插入排序(包含希尔排序)
插入排序 对于数组的排序是编程中常见的一种操作,本文将系统介绍编程常用的插入排序算法,根据具体实现上的区别,分为直接插入排序,二分插入排序和希尔排序. 直接插入排序.二分插入排序 为便于讨论,本文将数 ...
- 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...
先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...
- 希尔排序(缩小增量排序)(插入排序的优化版) C++代码实现及算法分析 恋上数据结构笔记
文章目录 复习概要 算法思想 算法流程 算法复杂度分析及稳定性 希尔排序代码正常版 希尔排序与插入排序代码对比 希尔排序个人青春版(别看以免走上歧途) 复习概要 算法思想与流程 分这么多组分别插入排序 ...
- 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)...
不多说,直接上干货! 插入排序包括直接插入排序.希尔排序. 1.直接插入排序: 如何写成代码: 首先设定插入次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不用 ...
- 排序:插入排序与希尔排序
插入排序 插入排序(英语:Insertion Sort)是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,在从 ...
- java 快速排序算法简单_排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序......
先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...
- 王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序
文章目录 1.插入排序 1.1直接插入排序 1.2折半插入排序 1.3希尔排序 2.交换排序 2.1冒泡排序 2.2快速排序 3.选择排序 3.1简单选择排序 3.2堆排序 4.归并排序 5.基数排序 ...
最新文章
- 推荐7个看似简约,实则惊艳的实用软件,建议收藏!
- WL 2009 professional【已解决】谢谢nooby跟海风
- eclipse恢复界面默认设置
- 洛谷——P1093 奖学金
- Asp.net的HTTP请求处理过程
- Tyvj 1176 火焰巨魔的惆怅
- 黑马程序员-JAVA高级视频_IO输入与输出-20天-9(切割合并文件)
- 《3D打印:正在到来的工业革命》——1.1节3D 技术打印是如何工作的
- 使用GDAL获取HDF等数据集中的图像
- Python:Django 项目中可用的各种装备和辅助
- python操作本地数据库,Python基础篇-Python连接Mysql操作数据库
- Python HackerRank 刷题 Pairs
- Linux USB 鼠标驱动程序详解
- 实习总结和大数据BI
- i7 1165g7和i7 9750h 哪个好
- java shp文件_java发布shp数据
- UGUI中实现文字下划线
- mybatis 使用大于号和小于号
- 线性代数系列(三)--向量空间
- 【Python】司徒卢威函数