关于第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双指算法,这里我用上图的列子进行讲述:

  1. 如果数列a为[20,13,7,2,12,11,9,1],将它折半拆为左数列L:[20,13,7,2],右数列R:[12, 11, 9, 1];
  2. 对数列L和R各自进行排序,方法用冒泡排序或其他排序手段都行;
  3. 之后用箭头(指代手指)指向数列L和R最小的元素,进行比较,并先输出这个最小的元素,如上图就是min(1,2)=1。
  4. 之后在该最小元素下移动箭头至下一个元素,将其与原来另一个数列元素进行比较,如上图就是数列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基准数从头到尾都不改动的)。
  1. 先从right指向的数与base对比:
  • 如果right<base,则将right值替换left值,然后left向右移一位,同时right值替换为空值,且right指针位置不变,然后让left此时指的数与base对比。
  • 如果right>base,则将right值替换right值(即保持不变),然后right向左移一位,同时left值替换为空值,且left指针位置不变,然后让right此时指的数与base对比。
  1. 重复上述操作,直到左右指针重叠,此时就直接将base值放入重叠位置即可。

总结上面的就是:先右开始对比,之后'小于则替换left并移left,然后新left对比base'或’大于则替换right并移right,然后新right对比base‘, left和right重合后用base替换。它的时间复杂度取决于base值真实在排序后的位置,如果base刚好为排序中间的位置,时间复杂度为Ο(nlog2n),如果base为数列最大值或最小值,则为Ο(n2)

[MIT6.006] 3. Insertation Sort, Mege Sort 插入排序,归并排序的更多相关文章

  1. [MIT6.006] 6. AVL Trees, AVL Sort AVL树,AVL排序

    之前第5节课留了个疑问,是关于"时间t被安排进R"的时间复杂度能不能为Ο(log2n)?"和BST时间复杂度Ο(h)的关系.第6节对此继续了深入的探讨.首先我们知道BST ...

  2. [MIT6.006] 4. Heaps and Heap Sort 堆,堆排序

    第4节课仍然是讲排序,但介绍的是一种很高效的堆排序. 在编程过程中,有时候会需要进行extrat_max的操作,即从一个数列里挨个抽取最大值并将其它从原数列中移除.而排序问题也可以看作是一个extra ...

  3. MIT6.006Lec03:插入排序,归并排序,递归树

    MIT6.006是算法导论课,Lec03主要讲插入排序,归并排序,以及分析方法(递归树)等. 插入排序,可以分为线性插入排序.二分插入排序,区别在于当把数组中某元素插入到前面的有序列表中时,前者遍历, ...

  4. [LeetCode] Insertion Sort List 链表插入排序

    Sort a linked list using insertion sort. 链表的插入排序实现原理很简单,就是一个元素一个元素的从原链表中取出来,然后按顺序插入到新链表中,时间复杂度为O(n2) ...

  5. [LeetCode] 147. Insertion Sort List 链表插入排序

    Sort a linked list using insertion sort. A graphical example of insertion sort. The partial sorted l ...

  6. LeetCode 147. Insertion Sort List 链表插入排序 C++/Java

    Sort a linked list using insertion sort. A graphical example of insertion sort. The partial sorted l ...

  7. 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 ...

  8. [Algorithms] Sorting Algorithms (Insertion Sort, Bubble Sort, Merge Sort and Quicksort)

    Recently I systematicall review some sorting algorithms, including insertion sort, bubble sort, merg ...

  9. ruby 数组array 排序sort 和sort!

    1. sort → new_ary click to toggle source sort { |a, b| block } → new_ary Returns a new array created ...

随机推荐

  1. go读取键盘输入两种方式

    一种scanf var x intfmt.Println("input a int number")fmt.Scan(&x)fmt.Printf("读取到内容:% ...

  2. go mod模式,引入自己的包,goland飘红

  3. Python常用模块之random和time

    常用模块: time: 分为三种格式: 1.时间戳:从1970年1月1日0点0分0秒到现在经过的秒数 用于时间间隔的计算 import time print(time.time()) 2.字符串显示时 ...

  4. flutter_bloc使用解析---骚年,你还在手搭bloc吗!

    前言 首先,有很多的文章在说flutter bloc模式的应用,但是百分之八九十的文章都是在说,使用StreamController+StreamBuilder搭建bloc,提升性能的会加上Inher ...

  5. Windos--jar包注册成服务

    1.下载资源 链接: https://pan.baidu.com/s/16asJXGudsRN23Rwra_qGZw 提取码: w2gv 解压后有五个文件 1.1注意事项 1.把你的生成的jar包放入 ...

  6. kettle学习笔记(三)— 定时任务的脚本执行

    kettle-定时任务 Kettle 的定时任务可以用kettle中的job工作来定时转换(缺点窗口不可关闭),同时也可以使用bat脚本来启动kettle的 '.ktr'转换. 注:这里对定时任务的时 ...

  7. 标签平滑(Label Smoothing)详解

    什么是label smoothing? 标签平滑(Label smoothing),像L1.L2和dropout一样,是机器学习领域的一种正则化方法,通常用于分类问题,目的是防止模型在训练时过于自信地 ...

  8. Django( 学习第四部 Django的views视)

    目录 视图层 JsonResponse对象 form表单之文件上传 request方法及属性 FBV与CBV JsonResponse对象 前端序列化 JSON.stringify() json.du ...

  9. 4G DTU模块的工作原理

    DTU是无线数据传输模块,4G DTU又被称4G模块,是4G网络进行远距离传输的设备,即串口服务器的无线版,其功能与串口服务器类似.         4G DTU是一种物联网无线数据终端,利用公用运营 ...

  10. 安装 Homebrew&iterm2&Oh My Zsh

    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/instal ...