【啊哈!算法】之二、插入排序

作者:jofranks 原创作品,转载请标明出处!版权所有,侵权必究!

来源:http://blog.csdn.net/jofranks


插入排序包括:直接插入排序,折半插入排序,希尔排序~!

OK,下面我们就来逐个讲解!

一、直接插入排序

直接插入排序属于稳定的排序,时间复杂性为O(n^2),空间复杂度为O(1)。

它的基本思想是:    

假设待排序数据存放在数组A[1..n]中,则A[1]可看作是一个有序序列,让i从2开始,依次将A[i]插入到有序序列A[1..i-1]中,A[n]插入完毕则整个过程结束,A[1..n]成为有序序列。


OK,现在我们来看一下排序的过程:

待排序数据:  25  54 8  54  21 1  97  2 73  15            (n=10)

i=2:               25 54  8 54  21  1 97  2  73  15

i=3:               8  25  54  54 21  1  97 2  73  15

i=4:               8  25 54 54  21 1  97  2 73  15

i=5:               21  25 54  54  1 97  2  73  15

i=6:               1  8  21 25  54  54  97 2  73  15

i=7:               1  8 21  25  54 54 97  2 73  15

i=8:               2  8 21  25  54 54  97  73  15

i=9:               1  2 8  21  25 54  54 73  97  15

i=10:             1  2 8 15  21 25  54  54 73  97           排序结束


可在数组中增加元素A[0]作为关键值存储器和循环控制开关。第i趟排序,即A[i]的插入过程为:

① 保存A[i]→A[0]

③ 如果A[j]<=A[0](即待排序的A[i]),则A[0]→A[j+1],完成插入;

   否则,将A[j]后移一个位置:A[j]→A[j+1];;继续执行③

对于上面的数据实例,i从2依次变化到10的过程中,j值分别为{1,0,3,1,0,6,1,7,3}



来看一下动画演示:直接插入排序动画演示


OK,下面来看一下代码,本代码是C语言!

void insert_sort(int a[], int N)
{int temp;int j;//从第二个元素开始逐个往下for(int i = 1; i < N; i++){if(a[i] >= a[i - 1])continue;temp = a[i];//与前面的元素比较,看是否需要插入j = i - 1;for(; a[j] > temp; j--){if(j < 0)break;a[j + 1] = a[j]; //后移			}a[j + 1] = temp;}
}






ok,现在我们来看一下C++版本的代码:(本代码取自维基百科)

#include <iterator>template<typename biIter>
void insertion_sort(biIter begin, biIter end){typedef typename std::iterator_traits<biIter>::value_type value_type;biIter bond = begin;std::advance(bond, 1);for(; bond!=end; std::advance(bond, 1)) {value_type key = *bond;biIter ins = bond;biIter pre = ins;std::advance(pre, -1);while(ins!=begin && *pre>key) {*ins = *pre;std::advance(ins, -1);std::advance(pre, -1);}*ins = key;}}






二、折半插入排序

折半插入排序算法是一种稳定的排序算法,时间复杂度仍然为o(n^2)!!!

本排序是在直接插入排序的基础上,减少了比较和移动的次数形成的!是对插入排序算法的一种改进!

具体操作:在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为a[high],则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较,如果比参考元素小,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]。


OK,我们来看一下代码! 这类似于二分法查找,相信大家都不陌生!

void binary_insert_sort(int a[], int N)
{int temp;int low, high,mid;for(int i = 1; i < N; i++){if(a[i] >= a[i - 1])continue;//开始二分low = 0;high = i - 1;temp = a[i];for(;low <= high;){mid = (low + high) / 2;if(temp > a[mid])low = mid + 1;else if(temp < a[mid])high = mid - 1;elsebreak;}//开始移动元素for(int j = i; j > low; j--){a[j] = a[j - 1];}a[low] = temp;}
}



三、希尔排序

该算法也是对直接插入排序的一种改进!也叫做递减增量排序算法!

该算法的性能提升至O(n log2 n)!他的最优时间是线性时间!


算法基本思想:

取一个小于n的整数S1作为增量,把所有元素分成S1个组。所有间距为S1的元素放在同一个组中。

第一组:{A[1],A[S1+1],A[2*S1+1],……}

第二组:{A[2],A[S1+2],A[2*S1+2],……}

第三组:{A[3],A[S1+3],A[2*S1+3],……}

……

第s1组:{A[S1],A[2*S1],A[3*S1],……}

先在各组内进行直接插人排序;然后,取第二个增量S2(<S1)重复上述的分组和排序,直至所取的增量St=1(St<St-1<St-2<…<S2<S1),即所有记录放在同一组中进行直接插入排序为止。


序号

1

2

3

4

5

6

7

8

9

10

原始数据

12

89

57

32

96

37

54

5

79

57

S1=5

组别

排序结果

12

54

5

32

57

37

89

57

79

96

S2=3

组别

排序结果

12

54

5

32

57

37

89

57

79

96

S3=2

组别

排序结果

5

32

12

37

57

54

79

57

89

96

S4=1

组别

排序结果

5

12

32

37

54

57

57

79

89

96


OK,通过上表可以看的清楚是如何排序的,有可能有的童鞋还是不清楚,那没事,我现在上传一个短动画,通过动画我相信你能够很好的理解shell排序!

希尔排序动画演示


ok,我们现在来看代码吧!

void shell_sort(int a[], int N)
{int temp, m;int i = 0;for(; i < N; ){i = i * 4 + 1;}//还是直接插入for(;i > 0;){for(int j = i; j < N; j++){m = j - i;temp = a[j];while(a[m] > temp){a[m + i] = a[m];m -= i;}a[m + i] = temp;}i = (i - 1) / 4;}
}




OK,再来看一段C++代码,来自维基百科!

template<typename T> void sort(std::vector<T>& v)
{const size_t s=v.size();for(int gap=s/2;gap>0;gap/=2)for(int i=gap;i<s;++i)for(int j=i-gap;j>=0;j-=gap)if(v[j+gap]<v[j]){T temp=v[j];v[j]=v[j+gap];v[j+gap]=temp;}
}




本节到此结束!



--------2012/7/31

--------jofranks 于南昌


转载于:https://www.cnblogs.com/java20130723/archive/2012/07/31/3211427.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

02Prism WPF 入门实战 - 建项

1.概要Prism介绍Github: https://github.com/PrismLibrary/Prism开发文档&#xff1a;https://prismlibrary.com/docs/Prism是一个框架&#xff0c;用于在WPF、Xamarin Forms、Uno Platform和WinUI中构建松散耦合、可维护和可测试的XAML应用程序。设计目标 为了实现下列目的&a…

rowspan 动态变化_使用colspan和rowspan动态删除html表中的多个列

好的&#xff0c;您的代码中的一个问题是&#xff0c;您删除了当前正在使用for进行迭代的单元格。我改变了你的第一个循环来完成所有反向&#xff1a;for (var i (rows[0].cells.length -1); i > 0; i--)&#xff0c;从后到前...所以没有索引在删除时发生变化。第二个问题是…

[转]Linux中如何自动启动服务

linux自动启动服务很简单&#xff0c;最简单的是把启动命令放到/etc/rc.d/rc.local文件里。这样就可以每次启动的时候自动启动服务了。例如对于 apache&#xff0c;编译好apache后会在安装目录的bin下生成apachectl文件&#xff0c;这是个启动脚本&#xff0c;我们只需要把这个…

一个C实现的线程池(产品暂未运用)

https://github.com/Pithikos/C-Thread-Pool

html首页 slider图片切换效果,jQuery插件Slider Revolution实现响应动画滑动图片切换效果...

jQuery插件Slider Revolution实现响应动画滑动图片切换效果2018-12-31编程之家https://www.jb51.cc这是一款非常强大的内容切换插件&#xff0c;它基于jQuery&#xff0c;它充分响应&#xff0c;支持移动设备&#xff0c;支持手机触摸&#xff0c;键盘翻页&#xff1b;它内置幻…

Asp.Net+Jquery.Ajax详解5-$.getScript

目录&#xff08;已经更新的文章会有连接&#xff0c;从7月25日开始&#xff0c;每2到3天更新一篇&#xff09;&#xff1a; Asp.NetJquery.Ajax详解1-开篇&#xff08;2012.07.25发&#xff09; Asp.NetJquery.Ajax详解2-$.Load&#xff08;2012.07.26发&#xff09; Asp.NetJ…

大数据告诉你:学历真的能改变命运!!

全世界只有3.14 % 的人关注了爆炸吧知识央视新闻曾做过关于高考的调查&#xff0c;结果有七成网友支持高考取消数学&#xff0c;看到新闻后&#xff0c;有一位网友却一针见血地评论道&#xff1a;数学考试存在的意义就是把这七成网友筛选掉。的确&#xff0c;虽然买菜不需要专业…

.net core 中如何有效屏蔽重复提交

咨询区 Guilherme Ferreira&#xff1a;我通过 post 方式向我的一个webapi中提交数据&#xff0c;然后插入到数据库中&#xff0c;在 ui端&#xff0c;当用户点击某一个 button 之后&#xff0c;代码会将 button 禁用&#xff0c;但因为某些原因&#xff0c;点击按钮的速度比禁…

小米8ios图标包下载_小米互传PC端抢先下载,免流量、高速互传,支持多设备共享...

小米早在MIUI初期就已经在开始探索手机与电脑之间互传文件的问题&#xff0c;MIUI"无线数据线"功能一直备受喜欢。手机与电脑之间互传&#xff0c;90%的用户都选择使用WX或者QQ来实现&#xff0c;它们互传的通道是互联网&#xff0c;无网时不可使用。为解决这个问题&…

sql server2008中怎样用sql语句创建数据库和数据表

这是简单用代码实现创建数据库和数据表的sql语句&#xff0c;如下&#xff1a; --调用系统数据库-- use master go /***防止你要创建的数据库同名&#xff0c;先把它删除掉****/ if Exists(select * from dbo.sysdatabases where nameTestDB) begin drop database TestDB end g…

[C++][IO]读写二进制文件

1. 以二进制方式读写结构体 struct Student {string name;string sex;int age; }void write(string filePath, const struct Student* stu, int n) {FILE *fp;int i;if((fpfopen(filePath,"wb"))NULL){printf("cant open the file");return;}for(i0;i<n…

HTML怎么做类似QQ聊天气泡,h5实现QQ聊天气泡的实例介绍

这篇文章主要介绍了HTML5实现QQ聊天气泡效果&#xff0c;用 HTML/CSS 做了个类似QQ的聊天气泡&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们可以参考一下今天自己用 HTML/CSS 做了个类似QQ的聊天气泡&#xff0c;以下是效果图&#xff1a;以下说下关键地方的样式…

高等数学的用处之一

1 只能说计算的真精准2 龙虾&#xff1a;我都准备半天了&#xff0c;你俩到底上不上&#xff1f;3 猫(≧^.^≦)&#xff1a;我为这个宿舍付出太多了&#xff01;4 请举一个日常生活中利用高等数学来解决问题的案例。5 男生做什么会让女生不开心7 人家拍的泸沽湖的水性杨花和我拍…

wp7 blogs

http://blog.csdn.net/jazywoo123/article/month/2012/04/3转载于:https://www.cnblogs.com/songtzu/archive/2012/08/09/2630573.html

k8s 查看ip地址属于哪个pod_Kubernetes Pod 如何获取 IP 地址

【编者的话】在学习 Kubernetes 网络模型的过程中&#xff0c;了解各种网络组件的作用以及如何交互非常重要。本文就介绍了各种网络组件在 Kubernetes 集群中是如何交互的&#xff0c;以及如何帮助每个 Pod 都能获取 IP 地址。Kubernetes 网络模型的核心要求之一是每个 Pod 都拥…

Fiddler抓包一键生成调用代码

首先我们的需求场景是用Fiddler抓到某个接口调用后&#xff0c;用代码来模拟调用&#xff0c;一般我们写代码会有3个步骤&#xff1a;1设置http请求相关的参数:header,method,url,cookie等2设置post的body(如果是post的话需要)3拿到返回的body(一般我们需要拿到接口的返回体进行…

frame框架的显示隐藏操作 (转)

下面是主要代码&#xff1a; index.htm <html><head><meta HTTP-EQUIV"Content-Type" CONTENT"text/html; charsetgb2312"><meta name"GENERATOR" content"Microsoft FrontPage 4.0"><meta name"Prog…

DexClassLoader的使用

版权声明&#xff1a;您好&#xff0c;转载请留下本人博客的地址&#xff0c;谢谢 https://blog.csdn.net/hongbochen1223/article/details/47146613 在Java环境中,有个概念叫做”类装载器(Class Loader)”,其作用是动态加载Class文件.标准的Java SDK中有一个ClassLoader类,借助…

arm开发tq2440上的c++裸奔程序

AVR实验做到LCD的时候&#xff0c;就发现proteus上没有现成合适的显示模块&#xff0c;网上找的模块不是按一般方法封装的&#xff0c;想来自己还有一块arm9开发板&#xff0c;大概大三、大四时候买的&#xff0c;已经搁置三年了。毕业这两年已经从51玩到AVR&#xff0c;虽然大…

这才是老公的正确用法,不吃就往死里打......

1 倒是好办法就是有点儿费爸爸▼2 一只被主人遗弃的小熊的奇幻旅程▼3 小子&#xff0c;你单身的命运gu7在你把美女老师撂倒那一刻就注定了...▼4 张萌姐姐自我肯定式唱歌▼5 &#xff1f;&#xff1f;&#xff1f;有被冒犯到▼6 听说昨天有个少年28岁就退休了▼7 哪个男…