当前位置: 首页 > news >正文

插入类排序

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

插入类排序的基本思路是在一个已经排好序的子记录上,每一步将下一个待排序的记录插入到已经排好序的记录子集中,直到将所有待排序记录全部插入为止。

1.直接插入排序

直接插入排序是最基本的插入排序算法,它的一趟操作是将第i个记录插入到前面i-1个已经排好序的记录中,在查找记录i的插入位置时,也在进行元素的移动。假设有一个待排序队列r[1,length],则整个排序过程需要n-1次趟。直接插入算法的实现如下:

1void insSort(int *r, int length)
2{
3    int i, j;
4 
5    printf("Sorting:\n");
6    for ( i = 2; i <= length; i++) {
7        r[0] = r[i];
8        j = i - 1;
9 
10        while (r[0] < r[j]) {
11            r[j + 1] = r[j];
12            j--;
13        }
14 
15        r[j + 1] = r[0];
16 
17        output(r, length);
18    }
19}

具体实现时,用一维数组来存储待排序的序列,其中0号元素备份待插入的记录。

2.折半插入排序

折半插入排序法与直接插入法类似,区别在于确定元素i插入的位置时利用折半查找法。每一趟排序的过程是先用折半查找法确定插入位置,再逐个进行元素的移动。

1void binSort(int *r, int length)
2{
3    int i, j;
4    int low ,high, mid;
5 
6    printf("Sorting:\n");
7    for ( i = 2; i <= length; i++) {
8        r[0] = r[i];
9        low = 1;
10        high = i - 1;
11 
12        while (low <= high) {
13            mid = (low + high) / 2;
14            if (r[0] < r[mid])
15                high = mid - 1;
16            else
17                low = mid + 1;
18        }
19 
20        for (j = i - 1; j >= low; j--)
21            r[j + 1] = r[j];
22        r[high + 1] = r[0];
23        output(r, length);
24 
25    }
26}

与直接插入法类似,数组r中的0号元素也备份了待插入的元素i。当确定了记录i的位置时,此时存在low=high+1这样的关系,接下来将low到i-1之间的元素都后移一位,最终记录i刚好插入空出来的位置中。

3.希尔排序

整个希尔排序的过程由若干次希尔插入组成,具体次数由增量数组delta中的元素个数n确定。在每一次的希尔插入算法中,将待排序的记录序列分成d 个稀疏子序列,每个稀疏子序列中元素之间的间隔正好为d。希尔插入算法就是将每一个子序列都按照直接插入法排列成有序,从而使得整个序列基本有序。上述过 程会重复n次,就是希尔排序算法的整个过程。

1void shellSort(int *r, int length, int *delta, int n)
2{
3    int i;
4    for ( i = 0; i < n; i++) {
5        shellInsert(r, length, delta[i]);
6    }
7}

第i趟希尔排序中,每个稀疏子序列中元素的间隔由delta[i]决定。但希尔算法的最后一趟排序,元素的间隔必需是1。因为最后一次希尔排序就相当于直接插入排序,但是此时整个记录序列已经几乎有序,因此移动的次数会大大减少。

1void shellInsert(int *r, int length, int d)
2{
3    int i, j;
4    int k;
5     
6    for (i = 1 + d; i <= length; i++) {
7        if (r[i] < r[i - d]) {
8            r[0] = r[i];
9             
10            for (j = i - d; j > 0 && r[0] < r[j]; j -= d) {
11                r[j + d] = r[j];
12            }
13            r[j + d] = r[0];
14        }
15    }
16    output(r, length);
17}

虽然希尔插入算法中需要依次将d个子序列排成有序,但是实际的实现过程却从第一个子序列的第二个记录(d+1)开始依次遍历整个序列,因为每个序列 中的元素都是由间隔d控制的,因此就相当于每个子序列各自排序。内部的for循环相当于对每个子序列进行直接插入排序,从当前的记录i(保存在r[0] 中)开始,依次扫描当前子序列之前的元素(每个元素的间隔为d,因此每次循环j都减少d)以确保插入何时的位置。

转载于:https://my.oschina.net/u/174242/blog/72942

相关文章:

  • ASP.NET MVC ModelState与数据验证【转】
  • Xenserver中启动虚拟机失败Vdi is not available的另外一种处理方法
  • 网站制作 时光网11月4日又回来了
  • Oracle_Database_11g_标准版_企业版__下载地址_详细列表
  • 整理软件成熟度等级3(CMMI3)之决策分析和决定
  • 虚拟内存安排
  • 变量应用:页面传Axure变量值
  • ubuntu系统常用命令操作
  • C#操纵XML小结_转载
  • VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确,应用程序未能启动”的问题...
  • 软件测试工程师的角度看论证学问
  • HDU 4370 0 or 1
  • 变量的自动初始化
  • 编译安装apache+mysql+php 支持jpg,gd等
  • Java程序员必知的8大排序
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • avalon2.2的VM生成过程
  • github从入门到放弃(1)
  • Go 语言编译器的 //go: 详解
  • JavaScript DOM 10 - 滚动
  • JavaScript 一些 DOM 的知识点
  • JSONP原理
  • STAR法则
  • Vultr 教程目录
  • 从重复到重用
  • 高程读书笔记 第六章 面向对象程序设计
  • 京东美团研发面经
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 批量截取pdf文件
  • 使用 Docker 部署 Spring Boot项目
  • 赢得Docker挑战最佳实践
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #define、const、typedef的差别
  • #if #elif #endif
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • $forceUpdate()函数
  • (4)logging(日志模块)
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (二)Eureka服务搭建,服务注册,服务发现
  • (分享)自己整理的一些简单awk实用语句
  • (规划)24届春招和25届暑假实习路线准备规划
  • (六)c52学习之旅-独立按键
  • (四)汇编语言——简单程序
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (一)VirtualBox安装增强功能
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)一些感悟
  • .net mvc部分视图
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • @Bean注解详解