[MIT6.006] 3. Insertation Sort, Mege Sort 插入排序,归并排序
关于第2节课《Models of Computation, Document Distance》由于内容过于简单,所以不在这里进行记录,它主要就是讲了Python很多操作是constant time(即无C语言地址指针机制,所以比较费时且耗内存),此外就是谈及了一个文档距离(Document Distance)问题,简单来说就是将文档内所有词形成词袋,用词袋下的特征算余弦距离。需要注意的就是余弦相似度越大,文档就越相似,而余弦距离=1-余弦相似度,因此余弦距离越小,代表文档相似度就越高。
第3节课只讲解了两种排序算法:冒泡排序(课程上用Insertation Sort讲述的思路就是冒泡排序,而实际上Insertation Sort应为插入排序)和归并排序(Merge Sort)。除了这两个还有其他排序方法例如:选择排序,快速排序,插入排序,堆排序,基数排序等等(这些会进行拓展补充或后面的课程会进行讲述)。
对各类排序方法整理如下:
| 排序算法 | 时间复杂度 |
| 冒泡排序 | Ο(n2) |
| 归并排序 | Ο(nlog2n) |
| 选择排序 | Ο(n2) |
| 插入排序 | Ο(n2) |
| 快速排序 | 极端Ο(n2),最好Ο(nlog2n) |
| 堆排序 | Ο(n) |
| 希尔排序 | Ο(ns) (1<s<2) |
| 基数排序 | Ο(nlog2(r)m) (r为基数,m为堆数) |
注:这里讲解上表中标蓝色和红色的排序算法。红色为课程讲解的算法。
1. 冒泡排序
冒泡排序就是像气泡一样使用pairwise swap成对交换的方式进行排序。下图显示了从左到右冒泡排序的机制:
key不断地移动,然后如果key下的数小于它前面的数,则进行两两交换,并保证换过的数大于左边最近的数,如果不是,那得继续交换,直到key达到最后一个元素,并且是以升序排列的。由于时间复杂度是看最坏情况,那么key的移动得n次,而若第n次对比交换很糟糕(例如1在数列最后面),那么对比得进行n次,最后时间复杂度就为Ο(n2)。
2. 归并排序
如下图,假设要对长度为n的数列A进行排序,归并排序的思想就是Divide&Conquer分开并克服,首先将A着半拆分为左数列L和有数列R,然后分别对L和R进行各自的排序,最后进行L和R的合并操作。

在该课程里,讲师提到了归并排序用的是一种叫Two Fingers双指算法,这里我用上图的列子进行讲述:
- 如果数列a为[20,13,7,2,12,11,9,1],将它折半拆为左数列L:[20,13,7,2],右数列R:[12, 11, 9, 1];
- 对数列L和R各自进行排序,方法用冒泡排序或其他排序手段都行;
- 之后用箭头(指代手指)指向数列L和R最小的元素,进行比较,并先输出这个最小的元素,如上图就是min(1,2)=1。
- 之后在该最小元素下移动箭头至下一个元素,将其与原来另一个数列元素进行比较,如上图就是数列R的箭头移至9, 数列L由于上一步不是最小值,所以箭头不变,则对比箭头所指元素的到min(2, 9)=2,输出结果。重复上述操作箭头到达各自数列末尾。
如下图所示,这里复杂度为Ο(nlog2n)。这里可以简单的分为两块:(1)二路归并需要进行log2n次;(2)双指算法对单次二路归并进行n次箭头移动(帮助进行最小值比较操作)。因此就是nlog2n次。
注:接下来选择排序,插入排序和快速排序的内容整理自《Python程序员面试算法宝典》一书。
3. 选择排序
选择排序的思想很简单:找到一个数列的最小值,然后将它与当前第一个记录交换。时间复杂度为Ο(n2)。
4. 插入排序
插入排序的思想也很简单:初始化一个空数列b,找到数列a中的最小值,然后插入到空数列b中,再不断找最小值,不断插入到数列b末尾即可。时间复杂度为Ο(n2)。

5. 快速排序
关于快排可以看知乎这篇文章的动图:https://zhuanlan.zhihu.com/p/93129029 , 看完就能理解它的机制,它是一种非常高效的排序算法,主要有三个零件:left左指针,right右指针和base基准数。举个例子如下图所示:
- 首先假设数列a为[6, 3, 7, 4, 1],则left左指针为数列a最开始的元素6,right右指针为数列b最末端的元素1,base基准数为left左指针6(注意这个base基准数从头到尾都不改动的)。
- 先从right指向的数与base对比:
- 如果right<base,则将right值替换left值,然后left向右移一位,同时right值替换为空值,且right指针位置不变,然后让left此时指的数与base对比。
- 如果right>base,则将right值替换right值(即保持不变),然后right向左移一位,同时left值替换为空值,且left指针位置不变,然后让right此时指的数与base对比。
- 重复上述操作,直到左右指针重叠,此时就直接将base值放入重叠位置即可。
总结上面的就是:先右开始对比,之后'小于则替换left并移left,然后新left对比base'或’大于则替换right并移right,然后新right对比base‘, left和right重合后用base替换。它的时间复杂度取决于base值真实在排序后的位置,如果base刚好为排序中间的位置,时间复杂度为Ο(nlog2n),如果base为数列最大值或最小值,则为Ο(n2)。
[MIT6.006] 3. Insertation Sort, Mege Sort 插入排序,归并排序的更多相关文章
- [MIT6.006] 6. AVL Trees, AVL Sort AVL树,AVL排序
之前第5节课留了个疑问,是关于"时间t被安排进R"的时间复杂度能不能为Ο(log2n)?"和BST时间复杂度Ο(h)的关系.第6节对此继续了深入的探讨.首先我们知道BST ...
- [MIT6.006] 4. Heaps and Heap Sort 堆,堆排序
第4节课仍然是讲排序,但介绍的是一种很高效的堆排序. 在编程过程中,有时候会需要进行extrat_max的操作,即从一个数列里挨个抽取最大值并将其它从原数列中移除.而排序问题也可以看作是一个extra ...
- MIT6.006Lec03:插入排序,归并排序,递归树
MIT6.006是算法导论课,Lec03主要讲插入排序,归并排序,以及分析方法(递归树)等. 插入排序,可以分为线性插入排序.二分插入排序,区别在于当把数组中某元素插入到前面的有序列表中时,前者遍历, ...
- [LeetCode] Insertion Sort List 链表插入排序
Sort a linked list using insertion sort. 链表的插入排序实现原理很简单,就是一个元素一个元素的从原链表中取出来,然后按顺序插入到新链表中,时间复杂度为O(n2) ...
- [LeetCode] 147. Insertion Sort List 链表插入排序
Sort a linked list using insertion sort. A graphical example of insertion sort. The partial sorted l ...
- LeetCode 147. Insertion Sort List 链表插入排序 C++/Java
Sort a linked list using insertion sort. A graphical example of insertion sort. The partial sorted l ...
- ORA-12805: parallel query server died unexpectedly ORA-04030 (sort subheap,sort key) 原因排查与解决方法
今日,某服务器pga调整为30G,_pga_max_size调整为8G之后(原来是2G,但是one passes语句较多,性能太低),执行出现ORA-12805: parallel query ser ...
- [Algorithms] Sorting Algorithms (Insertion Sort, Bubble Sort, Merge Sort and Quicksort)
Recently I systematicall review some sorting algorithms, including insertion sort, bubble sort, merg ...
- ruby 数组array 排序sort 和sort!
1. sort → new_ary click to toggle source sort { |a, b| block } → new_ary Returns a new array created ...
随机推荐
- 多路复用select和epoll的区别(转)
先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一.问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一 ...
- 网易新闻精彩评论集合(慢慢收集ing)
一.刚才在停车场看一男的开个Q7,怎么也停不进去.我迅速把车停好要过去帮忙,他死活不同意.我说,你刚也看见了我的停车技术了,肯定不能给你刮了.他干脆把窗户摇上了.如今的社会啊,人与人的互信程度为什么就 ...
- spring-boot-route(十七)使用aop记录操作日志
在上一章内容中--使用logback管理日志,我们详细讲述了如何将日志生成文件进行存储.但是在实际开发中,使用文件存储日志用来快速查询问题并不是最方便的,一个优秀系统除了日志文件还需要将操作日志进行持 ...
- 不要以为Bug写的好就是好程序员,其实这只占不到15%!
最近和一位从事多年架构工作的技术哥们见面,聊到了近期面试程序员的一些经历,谈到了"如何判断程序员水平高低"这个话题,颇有些感触,觉得有价值,因此花了些时间整理.分享给大家. 正 ...
- 【树形DP】NOI2003 逃学的小孩
题目大意 题目链接 PS:可能出题人为了提高难度故意加了很多废话--实际上题目是很简单的 在一棵树上找3个点A.B.C,使AB+BC最大,且满足AC>AB. 样例输入 4 31 2 12 3 1 ...
- k8s- centos7.8搭建
vmware16.0 centos7.8 1. 使用vmware安装 centos环境 cpu4个 内存4G 网络nat模式 2.配置网络 vim /etc/sysconfig/network-sc ...
- SonarQube 7.7 安装教程
SonarQube 7.7 安装教程 一. CentOS设置 1. 更换阿里源 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.ali ...
- Dubbo系列之 (七)网络层那些事(2)
辅助链接 Dubbo系列之 (一)SPI扩展 Dubbo系列之 (二)Registry注册中心-注册(1) Dubbo系列之 (三)Registry注册中心-注册(2) Dubbo系列之 (四)服务订 ...
- python 微信小程序自动化
微信小程序自动化 https://www.cnblogs.com/yyoba/python27 - FautoTesthttps://www.cnblogs.com/yyoba/p/9973731.h ...
- 微信小程序的账号找回。
之前注册过微信小程序,好久没用了,马上要开发微信小程序了,我今天登陆了一下突然发现 然后点击账号找回,按照流程同意点击下一步,到第二部时要输入搜索框里的提示. 这时的我早已忘了,百度搜了一下如何找回原 ...