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

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

这是直接插入排序和简单选择排序最大的不同。也是直接插入排序和简单选择排序同为时间复杂度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. Python中parameters与argument区别

    定义(define)一个带parameters的函数: def addition(x,y): return (x+y) 这里的x,y就是parameter 调用addition(3,4) 调用(cal ...

  2. ajax实现异步前后台交互,模拟百度搜索框智能提示

    1.什么是异步?在传统的网站项目中,填写一堆数据,最后点击提交,在点击提交的这一刻才实现数据提交,前后台交互.在你点击提交之前数据是没有提交到后台的.这样就会造成很大的不便.比如,我填了一大堆数据,结 ...

  3. 数组转换为List(Arrays.asList)后add或remove出现UnsupportedOperationException

    Java中,可以使用Arrays.asList(T... a)方法来把一个数组转换为List,返回一个受指定数组支持的固定大小(注意是固定大小)的列表.此方法同 Collection.toArray( ...

  4. x-pack-5.6.10激活教程

    x-pack-5.6.10激活教程 简介 X-Pack 已经作为 Elastic 公司单独的产品线,前身是 Shield, Watcher, Marvel, Graph, 和 reporting,先来 ...

  5. mysql 开发基础系列10 存储引擎 InnoDB 介绍

    一. 概述: InnoDB存储引擎提供了具有提交,回滚,和崩溃恢复能力的事务安全,对比MYISAM 的存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引.它的特点有如下: ...

  6. Android切换横竖屏不销毁前台Activity,也不影响后台Activity

    在切换屏幕方向的时候,Activity默认会走销毁->重建的生命周期,而有时候我们不希望如此,就需要做些额外的设置了: 1.在AndroidMainifest.xml中对应的Activity标签 ...

  7. JavaEE 要懂的小事:二、图解 Cookie(小甜饼)

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  8. leetcode — search-a-2d-matrix

    /** * Source : https://oj.leetcode.com/problems/search-a-2d-matrix/ * * * Write an efficient algorit ...

  9. 【原创】驱动卸载之ControlService函数

    BOOL WINAPI ControlService( _In_ SC_HANDLE hService, _In_ DWORD dwControl, _Out_ LPSERVICE_STATUS lp ...

  10. 【原创】驱动加载之OpenSCManager

    SC_HANDLE WINAPI OpenSCManager( _In_opt_ LPCTSTR lpMachineName, _In_opt_ LPCTSTR lpDatabaseName, _In ...