直接插入算法:每趟将一个待排序的关键字按照其值的大小插入到已经排好的部分有序序列的适当位置上,直到所有待排序的关键字都被插入到有序序列中为止。

理论上,在直接插入排序中第二层循环是可以提前结束的,即某个元素在寻找自己合适位置时并未循环遍历到序列最前端。

这是直接插入排序和简单选择排序最大的不同。也是直接插入排序和简单选择排序同为时间复杂度O(n2),但是直接插入排序效率更高的原因。

尤其是在待排序数据基本有序的时候,这种优势将极其明显。甚至此时直接插入排序要比时间复杂度为O(nlogn)的排序算法更加高效。

#include<iostream>
#include<string>
using namespace std; template <typename T>
void insertSelectionSort(T arr[],int n){
//不用考虑第0个元素,因为插入排序初始情况下,第0个元素自身就是有序的
for(int i=;i<n;i++){
//寻找arr[i]合适的插入位置
//每次比较的是当前元素和当前元素的前一个元素的比较,故判断条件是j>0而不是j>=0
for(int j=i;j>&&arr[j-]>arr[j];j--)
swap(arr[j],arr[j-]);
}
} int main(){
int a[]={,,,,,,,,,};
insertSelectionSort(a,);
for(int i=;i<;i++)
cout<<a[i]<<" ";
cout<<endl; float b[]={3.3f,2.2f,1.1f};
insertSelectionSort(b,);
for(int j=;j<;j++)
cout<<b[j]<<" ";
cout<<endl; string c[]={"D","C","B","A"};
insertSelectionSort(c,);
for(int k=;k<;k++)
cout<<c[k]<<" ";
cout<<endl; return ;
}

输出结果:

但是,如果我们进行算法性能测试,我们会发现上面的代码并未将这种效率高的优势显示出来。

原因是在这段代码中存在大量的数值交换,而每一次数值交换都包括三次赋值的操作,在本例中还包括访问数组索引所在位置的时间,这些是比简单的比较耗时更多的存在。

所以我们可以对上面关键代码进行优化。


template <typename T>
void insertSelectionSort(T arr[],int n){ for(int i=;i<n;i++){
//将待排序的关键字复制出来,拿它与它前面的元素进行比较
T e=arr[i];
//需要把j的定义拿到for循环的外面,因为最后要在索引j指定的位置(比较后的目标位置)插入复制出来的关键字e
int j;
for(j=i;j>&&arr[j-]>e;j--)
//将比待排序关键字的大的关键字依次后移
arr[j]=arr[j-]; arr[j]=e;
}
}

在这里我们不再调用swap函数进行数值的交换,而是全都是用赋值语句完成相应的操作。

就大大优化了算法。

需要说明一下的是:对于直接插入排序,一趟排序后并不能确保一个关键字到达其最终位置。

直接插入排序算法的C++实现的更多相关文章

  1. 排序系列 之 折半插入排序算法 —— Java实现

    基本思想: 折半插入算法是对直接插入排序算法的改进,排序原理同直接插入算法: 把n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只有一个元素,无序表中有n-1个元素:排序过程即每次从无序表中 ...

  2. 排序系列 之 直接插入排序算法 —— Java实现

    直接插入排序算法 基本思想: 把n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只有一个元素,无序表中有n-1个元素:排序过程即每次从无序表中取出第一个元素,将它插入到有序表中,使之成为新的 ...

  3. 插入排序---希尔插入排序算法(Javascript版)

    取一个小于n的整数作为第一个增量,把序列分组.所有距离为增量的倍数的元素放在同一个组中.先在各组内进行直接插入排序:然后,取第二个增量(第二个<第一个)重复上述的分组和排序,直至所取的增量=1, ...

  4. 插入排序---直接插入排序算法(Javascript版)

    将n个元素的数列分为已有序和无序两个部分. 数列:{a1,a2,a3,a4,…,an} 将该数列的第一元素视为有序数列,后面都视为无序数列: {{a1},{a2,a3,a4,…,an}} 将无序数列中 ...

  5. 插入排序算法--直接插入算法,折半排序算法,希尔排序算法(C#实现)

    插入排序算法主要分为:直接插入算法,折半排序算法(二分插入算法),希尔排序算法,后两种是直接插入算法的改良.因此直接插入算法是基础,这里先进行直接插入算法的分析与编码. 直接插入算法的排序思想:假设有 ...

  6. PHP实现插入排序算法

    插入排序(Insertion Sort),是一种较稳定.简单直观的排序算法.插入排序的工作原理,是通过构建有序序列,对于未排序的数据,在有序序列中从后向前扫描,找到合适的位置并将其插入.插入排序,在最 ...

  7. 《算法4》2.1 - 插入排序算法(Insertion Sort), Python实现

    排序算法列表电梯: 选择排序算法:详见 Selection Sort 插入排序算法(Insertion Sort):非常适用于小数组和部分排序好的数组,是应用比较多的算法.详见本文 插入排序算法的语言 ...

  8. 直接插入排序算法:ArrayList实现和数组实现

    直接插入排序算法思想: 排序区间R[1..n]: 在排序的过程中,整个排序区间被分为两个子区间: 有序区R[ 1 ... i-1 ]和无序区R[ i ... n ]: 共进行n-1趟排序,每趟排序都是 ...

  9. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

  10. C/C++ -- 插入排序算法

    索引: 目录索引 参看代码 GitHub: Sort.cpp 代码简要分析说明: 1.for(int i=1;i<nSize;i++) 这个外层的for循环, [0][1],[1][2],[2] ...

随机推荐

  1. Spring lazy-init 原理分析

    普通的bean的初始化是在容器启动初始化阶段执行的,而被lazy-init修饰的bean 则是在从容器里第一次进行context.getBean(“”)时进行触发.Spring 启动的时候会把所有be ...

  2. lazy_import源码解析(原创)

    参考链接: An approach to lazy importing in Python 3.7(这个是参考源) Python3.7中一种懒加载的方式(中文翻译) 原博客核心: 以前的两种惰性/延迟 ...

  3. Python编程Day3—基本运算符、数据类型

    一.基本运算符 1.算数运算 print(10/3) print(10//3) print(10%3) print(10**3) 2.比较运算 print(10==10) print(10!=10) ...

  4. Nexus私服搭建

    maven私服的搭建 --> maven -->{ 1,本地仓库(从中央仓库下载保存到本地的或者自己到网上下载的jar文件包) 2,远程仓库 -->{ 1,中央仓库(maven官方j ...

  5. xcodebuild构建时报错unknown error -1=ffffffffffffffff Command /bin/sh failed with exit code 1

    CI今日构建时报出如下错误: /Users/xxx/Library/Developer/Xcode/DerivedData/Snowball-ebllohyukujrncbaldsfojfjxwep/ ...

  6. 《HelloGitHub月刊》第 02 期

    <HelloGithub>第02期 兴趣是最好的老师,而<HelloGitHub> 就是帮你找到兴趣! 因为我比较熟悉python语言,所以月刊中python语言的项目居多,个 ...

  7. Java IO API记录

    文件路径: public static final String FILEPATH= File.separator+"Users"+ File.separator+"xu ...

  8. Django使用Channels实现WebSocket--下篇

    希望通过对这两篇文章的学习,能够对Channels有更加深入的了解,使用起来得心应手游刃有余 通过上一篇<Django使用Channels实现WebSocket--上篇>的学习应该对Cha ...

  9. linux平均负载的理解及原因排查

    当系统响应缓慢时,一般会用top或uptime命令查看系统负载是否过高. 例如输入uptime命令显示如下图,其中23:47:19表示现在的时间,up 260 days,14:39表示系统运行了多久, ...

  10. Perl面向对象(2):对象

    本系列: Perl面向对象(1):从代码复用开始 Perl面向对象(2):对象 Perl面向对象(3):解构--对象销毁 第3篇依赖于第2篇,第2篇依赖于1篇. 已有的代码结构 现在有父类Animal ...