algorithm -- 插入排序
插入排序是《算法导论》中第一个介绍的算法,详细分析了插入排序的原理,执行过程,证明了算法的正确性。同时也引出了算法分析和算法分析常用的方法。
此文对原文作个转述,检验学到的知识。
文中使用了伪代码写出了插入排序的执行过程,在这里用C++重写:
void insertSort( int * arr, int count )
{
if( arr == nullptr || count == 0 )
{
return;
}
for( int i = 0; i < count; i++ )
{
int tem = arr[ i ];
int j = i;
while( j > 0 && tem > arr[ j - 1 ] )
{
arr[ j ] = arr[ j - 1 ];
--j;
}
arr[ j ] = tem;
}
}
插入排序类似于许多人打扑克摸牌的整理方法一样,每次从桌面上摸起一张,与原有的牌比较,播放正确的位置,这样无论何时,手中的牌总下排好序的。
《导论》中使用循环不变式证明插入排序的正确性
循环不变式有三个性质:
- 初始化:循环开始时应该是正确的
- 保持:循环在某一次迭代开始之前是正确的,那么下一次迭代开始之前,它也是应该保持正确
- 终止:当循环结束时,不变式给了我们一个有用的性质,它有助于表明算法是正确的
前两个性质成立时,就能保证循环不变式在每一论迭代开始之前,都是正确的。这是数学归纳法相似,只是多了终止。
《导论》是这么说的,怎么理解、使用,则需要实践和验证。
我理解的循环不变式的第二条是:在前一次操作正确的情况下,保证本次操作正确。这也应该是算法设计中的重点。
拿上面的算法来实践下循环不变式:
int * arr, int count
输入待排序的数组指针和数组大小,在本例中正在排序的元素前是排序好的(相当于手中的扑克),后是未排序的(相当于桌面的牌),tem 保存中间量
初始化:当 i = 0; 时,排序好的是arr[0],正在排序的也是arr[0],此时已经排好序了。
保持:第_i_个元素排序时,前面arr[0]~arr[i-1]是排好序的,进入_while_循环为_i_排序,这里得保证排序正确,不然下次排序的前提条件是错误的,算法也就错误了。那么来看下_while_循环做了什么:
首先 j = i,从排序好的部分尾部开始,向前比较每一个元素大小,当第_i_个元素大于第_j-1_个元素时arr[ j ] = arr[ j - 1 ];即将排序好(小于第_i_个元素)的数向后移,当条件不成立时循环结束,第_i_个元素插入到_j_的位置,此时数组中arr[0]~arr[i]是排序好的,下次迭代前正确终止:当i == count;时循环终止,数组的前_i-1_个数是排序好的,而数组大小为 conut 个,数组最后一个元素的下标是 conut-1 等于此时的 i-1 ,所以此时数组已排好序了,算法正确。
好了此时能条理清晰的说明插入排序是正确的,已经有点吃力了,后面的算法分析就放到后面再讨论,先抄一段:
- 算法分析是指对算法所需要的资源进行预测,内存、通信带宽或计算机硬件资源以及时间等
- 算法分析主要考察的最坏情况
- 算法的增长量级
algorithm wiki 
algorithm -- 插入排序的更多相关文章
- 【Algorithm】插入排序
一. 算法描述 插入排序具体算法描述如下: 从第一个元素开始,该元素可以认为已经被排序 取出下一个元素,在已经排序的元素序列中从后向前扫描 如果该元素(已排序)大于新元素,将该元素移到下一位置 重复步 ...
- 【Algorithm】插入排序法
通常人们整理桥牌的方法是一张一张的来,将每一张插入到其他已经有序的牌中的适当位置. • 思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的序列的合适位置,直到全部插入排序完为止. Jav ...
- The insertion sort algorithm expressed in pseudocode - 插入排序
Computer Science An Overview _J. Glenn Brookshear _11th Edition procedure Sort (List) N ← 2; while ( ...
- 排序算法(sorting algorithm)之 插入排序(insertion sort)
https://en.wikipedia.org/wiki/Insertion_sort loop1: 4,6,1,3,7 -> 4,6,1,3,7 loop2: 4,6,1,3,7 -> ...
- [LeetCode] Insertion Sort List 链表插入排序
Sort a linked list using insertion sort. 链表的插入排序实现原理很简单,就是一个元素一个元素的从原链表中取出来,然后按顺序插入到新链表中,时间复杂度为O(n2) ...
- algorithm -- 选择排序
选择排序是<导论>第一章课后习题,仿照插入排序,再次运用循环不变式来证明下算法的正确性,C++ 源码: // 交换函数 void swap( int& a, int& b ...
- 数据结构(DataStructure)与算法(Algorithm)、STL应用
catalogue . 引论 . 数据结构的概念 . 逻辑结构实例 2.1 堆栈 2.2 队列 2.3 树形结构 二叉树 . 物理结构实例 3.1 链表 单向线性链表 单向循环链表 双向线性链表 双向 ...
- 疯狂的Java算法——插入排序,归并排序以及并行归并排序
从古至今的难题 在IT届有一道百算不厌其烦的题,俗称排序.不管是你参加BAT等高端笔试,亦或是藏匿于街头小巷的草根笔试,都会经常见到这样一道百年难得一解的问题. 今天LZ有幸与各位分享一下算法届的草根 ...
- MIT算法导论——第一讲.Analysis of algorithm
本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...
随机推荐
- StringBuffer(线程安全)StringBuilder(非线程安全)
StringBuffer属于线程安全,相对为重量级 StringBuilder属于非线程安全,相对为轻量级 线程安全的概念: 网络编程中许多线程可能会同时运行一段代码.当每次运行结果和单独线程运行的结 ...
- python之路1(初识python)
python简史: python我认为特性就是简洁,灵活,高效. python重要版本: python1991年问世, python2.4:2004,同年django框架诞生. python2.6:2 ...
- 微信小程序-数据缓存
每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStorageSync).wx.getStorage(wx.getStorageSync).wx.clearSt ...
- Highcharts动态添加点数据
Highcharts用来作为图表数据的展示十分方便,效果也比较好.highcharts不仅可以实现死数据的展示,也能实现动态数据的实时添加显示,类似财经股票的实时刷新效果,实现过程并不难,大致如下. ...
- Javascript 知识点整理
1.十进制和十六进制相互转换 /* 十六进制转十进制 */ var test = FF; var x = parseInt(test ,16); //方法一 x = parseInt('0x'+tes ...
- GitHub 用到的英语
1.Github首页Pull requests Issues Gist请求 问题 要点Learn Git and GitHub without any code!没有任何代码学习Git和GitHu ...
- web-app子元素
?表示可选,最多一个:*表示0个或多个. web-app (icon?, display-name?, description?, distributable?, context-param*, fi ...
- 【cpp】Vector
这vector 很有用 // compile with: /EHsc #include <vector> #include <iostream> int main() { us ...
- display:inline、block、inline-block的区别
display:block就是将元素显示为块级元素. block元素的特点是: 总是在新行上开始: 高度,行高以及顶和底边距都可控制: 宽度不设是它的容器的100%,除非设定一个宽度 <div& ...
- Java_ToolKit用法
转自:http://blog.sina.com.cn/s/blog_9e4556250100z5kv.html 此类是所有 Abstract Window Toolkit 实际实现的抽象超类.Tool ...