1.直接插入排序

直接插入排序的过程可以理解为一个固定长度的数组被分为两个集合,即已排序集合和未排序。

开始时已排序集合为空,而未排序集合即为整个数组。当排序开始后插入一个对象,已排序集合元素数目加1,相应地未排序集合元素数目减1,重复插入过程直至将未排序集合清空为止,这时排序集合就是最终结果。如下图:

C++实现如下,为了使得程序可以对各种基本数据类型都能排序,使用了模板类,注意模板类的类声明和成员函数实现必须在同一个cpp文件里面,不能分开!!

 #ifndef INSERTSORT_H
#define INSERTSORT_H
#include <vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector; template <typename T>
class InsertSort
{
private:
unsigned len;
vector<T> list;
public:
InsertSort(vector<T> _list, unsigned _len)
{
for (unsigned i = ; i < _len; ++i) list.push_back(_list[i]);
this->len = _len;
}
void insertSort()
{
T insertNum;
for (unsigned i = ; i < len; ++i) // Insert number for len times
{
insertNum = list[i]; // The number is to be inserted
unsigned j = i;
while (j && insertNum < list[j-]) // Find the position to insert the target number in
{
list[j] = list[j - ];
--j;
}
list[j] = insertNum;
}
}
void out()
{
for (unsigned i = ; i < len; ++i)
{
cout << list[i] << " ";
if ((i+)% == ) cout << endl;
}
cout << endl;
}
};
#endif

2.二分插入排序

因为直接插入排序在搜索插入位置的时候,效率很低,对于大数组,尤其不适用,于是采用二分插入排序,又叫折半插入排序,二分插入排序是采用折半查找法寻找要插入的位置。

下面演示了折半查找法在目标数组中确定数字35的位置:

  • 首先确定目标数组的中间位置数字为45
  • 由于45 > 35,所以降原数组折半并取左半部分子数组作为搜索目标,左半部分的中间元素为23
  • 由于23 < 35,所以再折半,选择子数组的有半部分作为搜索目标
  • 而35 < 36,于是确定35的位置在23和36之间。

下面给出C++实现:

 #ifndef BINARYINSERTSORT_H
#define BINARYINSERTSORT_H
#include <vector>
using std::vector;
template <typename T>
class BinaryInsertSort
{
private:
int len;
vector<T> list;
public:
BinaryInsertSort(vector<T> _list, int _len)
{
for (int i = ; i < _len; ++i) list.push_back(_list[i]);
this->len = _len;
}
void binaryInsertSort()
{
int middle;
for (int i = ; i < len; ++i)
{
T insertNum = list[i];
int left = ;
int right = i - ;
while (left <= right)//Find the insertation position with binary search
{
middle = (left + right) / ;
if (insertNum > list[middle])
left = middle + ;
else
right = middle - ;
}
for (int j = i; j > left; --j) list[j] = list[j-];
list[left] = insertNum;
}
}
void out()
{
for (unsigned i = ; i < len; ++i)
{
cout << list[i] << " ";
if ((i+)% == ) cout << endl;
}
cout << endl;
}
};
#endif

3.测试运行

 #include "InsertSort.h"
#include "BinaryInsertSort.h"
#include <vector>
using namespace std; const unsigned numEle = ;
int data[numEle] = {,,,,,,,}; int main()
{
vector<int> testData;
for (unsigned i = ; i < numEle; ++i) testData.push_back(data[i]);
//InsertSort<int> test(testData, numEle);
//test.insertSort();
BinaryInsertSort<int> test(testData, numEle);
test.binaryInsertSort();
test.out();
return ; }

4. 参考文献

左飞:C++数据结构原理与经典问题求解

数据结构复习:直接插入排序与二分插入排序的C++实现的更多相关文章

  1. 我的Java开发学习之旅------>Java经典排序算法之二分插入排序

    一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为采用折半比较,即可得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比较, ...

  2. 数据结构复习:希尔排序的C++实现

    1.原理介绍 希尔排序又称为缩小增量排序,由D.L.Shell在1959年提出而得名. 该算法先取一个小于数据表中元素个数 n 的整数gap, 并以此作为第一个间隔,将数据分为gap个子序列,所有距离 ...

  3. 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  4. 向Array中添加二分插入排序

    二分插入排序思路 先在有序区通过二分查找的方法找到移动元素的起始位置,然后通过这个起始位置将后面所有的元素后移. 二分插入排序实现 Function.prototype.method = functi ...

  5. java实现 排序算法(鸡尾酒排序&选择排序&插入排序&二分插入排序)

    1.鸡尾酒排序算法 源程序代码: package com.SuanFa; public class Cocktial {    public static void main(String[] arg ...

  6. 排序算法(2)--Insert Sorting--插入排序[2]--binary insertion sort--折半(二分)插入排序

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.基本思想 二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可 ...

  7. ZT 二分插入排序也称折半插入排序

    二分插入排序也称折半插入排序,基本思想是:设数列[0....n]分为两部分一部分是[0...i]为有序序列,另一部分是[i+1.....n]为无序序列,从无序序列中取一个数 x ,利用二分查找算法找到 ...

  8. c语言描述的二分插入排序法

    #include<stdio.h> #include<stdlib.h> //二分插入排序法 void BinsertSort(int a[],int n){ int low, ...

  9. js【生成规定数量不重复随机数】、【冒泡排序】、【鸡尾酒排序】、【选择排序】、【插入排序】、【未完工的二分插入排序】------【总结】

    [生成规定数量不重复随机数] function creatRandom( num ){ var randomLen = num, ranArr = [], thisRan = null, whileO ...

随机推荐

  1. 14、NFC技术:使用Android Beam技术传输文本

    Android Beam的基本理念 Android Beam的基本理念就是两部(只能是两部)NFC设备靠近时(一般是背靠背),通过触摸一部NFC设备的屏幕,将数据推向另外一部NFC设备.在传递数据的过 ...

  2. PHP 获取网页301|302真实地址

    function getRealURL($url){ $header = get_headers($url,1); if (strpos($header[0],'301') || strpos($he ...

  3. bzoj 3270 博物馆(高斯消元)

    [题意] 两人起始在s,t点,一人pi概率选择留在i点或等概率移动,问两人在每个房间相遇的概率. [思路] 把两个合并为一个状态,(a,b)表示两人所处的状态,设f[i]为两人处于i状态的概率.则有转 ...

  4. Container View Controller

    有时候,我们的Controler中包含有另一个controler view的view时,可以使用这种方式. https://developer.apple.com/library/ios/featur ...

  5. 第三百二十八天 how can I 坚持

    今天电脑快把我搞疯了,一天得死机快十次,不知道怎么回事,最后升级了win10,感觉就是比较好. 哎,成了这个样子,当初为什么又让我抽中了那个签,搞不懂啊,这都是为啥. 我哪里错了,还是冥冥中自有天意, ...

  6. G450 Ubuntu14 无线网卡解决

    安装了Ubuntu14,与win7共存. grub界面启动. G450的本子,安装完之后发现无线网卡不能被驱动,但能被之别到,因此激活一次broadcom sta wireless driver 命令 ...

  7. class list

    class list(object): """ list() -> new empty list list(iterable) -> new list ini ...

  8. I/O小总结

    //判断不存在就创建目录 ,然后拷贝文件 DirectoryInfo di = null; if (!Directory.Exists(n.Attribute("value").V ...

  9. HDU3033I love sneakers!(分组背包)

    http://acm.hdu.edu.cn/showproblem.php?pid=3033 本题的意思就是说现在有n种牌子的鞋子,每种品牌有一些不同的鞋,每双鞋子都有一个特定的权值,现在要求每种品牌 ...

  10. static和extern的区别

    extern(外部) 1.对函数      完整的定义一个外部函数(可以省略extern)      完整的声明一个外部函数(可以省略extern) 2.对变量      只能声明一个外部变量(不能省 ...