当前位置: 首页 > news >正文

【MIT算法导论】算法分析与基础知识

前言

本文是B站《算法导论》MIT公开课的随课笔记,关于内容和笔记格式有问题的朋友欢迎私信交流~


一.基本概念

  1. 算法分析:

是对计算机性能以及计算机资源的研究

  1. 除去【性能】,程序还有哪些重要的性质:
  • 正确性,简洁,可维护性,健壮性,模块性,安全性…

即使存在着以上这些比性能更加重要的特质,那么为什么还要研究算法与性能?

  • 性能的好坏决定可行与否,算法总是处在前沿阶段,设想将不可行变得可行。
    性能之于上面这些其他特质的关系就相当于一叠钞票和一系列生存物资的关系,是基础保障。

    所以我们需要研究算法和性能,是因为有了性能的保障,我们才能更好地追求程序的其他特性。

二.引论问题——排序

问题描述:将一系列元素(a1,a2,…aN)进行排序后重新输出,要求排序后的元素是非递减的。

问题解决:插入排序等多种经典排序方案

(一)插入排序(Insertion Sort)

  1. 概念、过程与思想

(1)本质:就是程序始终维持一个有序的部分,表示数组中已经排序好的部分;而程序运行就是为了能够使得这一部分不断增长,直到数组的所有部分都是排序好的。
在这里插入图片描述

(2)过程:伪代码+过程理解

void InsertionSort(A[],n)//对数组A[1...n]中的元素进行排序
{
  for(int j = 2;j<=n;j++){
    int key = A[j];
    int i = j-1;
    while(c>0 && A[i]>key){
      A[i+1] = A[i];
      i--;
    }
    A[i+1] = key;
  }  
}

①上述第一个for循环,是每次都考虑一个未有序部分的元素。

②第二个while循环,就是对每一个元素,选择一个合适的位置进行插入,而插入点之后的元素,都要顺次后移一个位置。

  1. 运行时间分析

运行时间Runtime相关的因素:
输入本身(结构)/
输入规模 /
运行时间的上界

(1)最好结果
是考虑了某些特定的输入,具有欺骗性质的假象,作用不大。

(2)平均结果
考虑一个加权平均的计算,每一种可能出现的输入的耗时和该情况出现的概率对应的加权平均。

如何得知每种运行结果的概率呢?
——需要做一个假设,假定运行情况结果符合均匀分布。

(3)最坏结果

  • 评估最坏结果时常使用的一些参量:
    计算机 (相对/绝对)速度
  • 最坏结果代表了程序运行的上界,这往往代表着对用户的一种承诺,具有实际意义。

(二)算法的大局观【渐进思想】

——忽略掉那些依赖于机器的常量
——不是去检查实际的运行时间,而是关注运行时间的增长

  1. 【关注时间增长的思路】渐进符号

θ符号,其作用是:为写进的公式,舍去它的低阶项,忽略前面的常数因子。
在这里插入图片描述

  1. 渐进符号的意义

E.g.一个θ(n2)的算法始终要比θ(n2)的算法运行快

①理解1:当n→∞时,你始终可以找到一个n,使得n2小于n3
②理解2:上述结论纵然是在一个慢速计算机上也是适用的。

渐进符号能同时满足我们对相对和绝对速度的双重比较。

  1. 从工程角度合理利用渐进思想
    在这里插入图片描述

①在以上的两个图形比较下,总能找到一个输入规模状态点n0,使得之后所有n3都要慢于n2

②但是很多时候,n0这个点在实际工程问题中可能因为过大而不合理。所以我们常常也会关注一些慢速算法,因为它们仍然可以在合理规模的输入下运行得更快

(三)插入排序worst case下的复杂度的渐进分析

  1. 分析原则

①因为是渐进分析,所以我们把过程中的每项操作都看成是相差无几的基本操作

②我们采用计数的方法,是内存引用计数,实际上访问了某个变量的次数。

③因为是worst case,所以考虑的是对输入逆序的一组元素,通过排序排列成正序的情况。

  1. 分析结果
    在这里插入图片描述

根据渐进分析,在输入规模较小的情况下,插入排序的效率还是可观的,但是输入规模一旦增大,则效率会降低。

(四)归并排序的基本思想和渐进分析

  1. 算法框架和伪码表示
void MergeSort(A[])//对数组A[1...n]中的元素进行有向排序
{
  if(n==1)
      return ;
  sort(A,1,n/2);
  sort(A,n/2+1,n);
  merge(A,1,n/2,n/2+1,n);
}

(1)思想:归并排序的本质就是,分而治之。先让待排序的一组元素,分成两组已经有序的元素,再对这两组已经有序的元素进行合并。

(2)merge操作的理解
在这里插入图片描述

//对有序数组a和有序数组b中的元素进行合并
void merge(){
  int i = 0,j = 0;//指向a,b数组中元素的指针
  int p = 0;
  while(i<a.length()&&j<b.length()){
      if(a[i]<b[j]){
          c[p++] = a[i++];
      }
      else{
          c[p++] = b[j++];
      }
  }
  while(i<a.length()){
      c[p++] = a[i++];
  }
  while(j<b.length()){
      c[p++] = b[j++];
  }
}
  1. 时间复杂度的渐进分析

(1)merge操作的渐进分析

  • 线性时间
  • Time = θ(n) on n total elements

(2)递归程序的时间递归推导
在这里插入图片描述
(3)推导出T(n)的通用表达式——递归树方法
在这里插入图片描述

在渐进情况下,nlogn的复杂度是要低于n2的复杂度的。

也就是说,渐进情况下,归并排序胜过插入排序。

相关文章:

  • 【微积分的本质|笔记】隐函数求导的意义与理解
  • 【微积分的本质|笔记】极限
  • 【微积分的本质|笔记】泰勒级数
  • 【微积分的本质|笔记】面积和斜率的联系
  • 【台大李宏毅|ML】课程介绍
  • 【MIT算法导论】渐进符号、递归与解法
  • 【CMU|深入理解计算机系统】Bits,Bytes and Integers
  • 【矩阵论】线性空间与线性变换(1)
  • 【台大李宏毅|ML】Regression
  • 【矩阵论】线性空间与线性变换(2)
  • 归并排序算法的实现与分析
  • 【MIT算法导论】分治法
  • 【矩阵论】线性空间与线性变换(3)(4)
  • 【矩阵论】线性空间与线性变换(5)
  • 【2/3/4-sum问题】算法设计剖析
  • Hexo+码云+git快速搭建免费的静态Blog
  • Java程序员幽默爆笑锦集
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • Linux下的乱码问题
  • React+TypeScript入门
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Spark RDD学习: aggregate函数
  • spring + angular 实现导出excel
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 开源SQL-on-Hadoop系统一览
  • 爬虫模拟登陆 SegmentFault
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 线性表及其算法(java实现)
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​LeetCode解法汇总518. 零钱兑换 II
  • #在 README.md 中生成项目目录结构
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • $L^p$ 调和函数恒为零
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (排序详解之 堆排序)
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (原創) 未来三学期想要修的课 (日記)
  • .apk文件,IIS不支持下载解决
  • .bat批处理(一):@echo off
  • .bat批处理出现中文乱码的情况
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .equals()到底是什么意思?
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET上SQLite的连接
  • .ui文件相关
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • @DependsOn:解析 Spring 中的依赖关系之艺术
  • @RestController注解的使用