计算机科学及编程导论(8)算法的复杂度

1.基于问题规模的复杂度计算方法

在考虑时间效率的时候,面临以下两个问题:输入规模以及步骤。

输入规模受很多因素影响:参数大小、参数类型(数组、元组的存取小绿是不同的),而且不同操作步骤(加减、判断)时间也不是相同的,为了方便计算,我们需要建立以下的假设:

假设从计算机取得任何变量的时间是相同的

假设基本操作时间恒定

接下来就可以考虑以下几种情况:

最好情况:何种输入会使得程序的运行时间最短?

最坏情况:何种输入会使得程序的运行时间最长?

平均情况

如果考虑平均情况的话,就要去设想问题输入规模的分布情况,这样大大增加了计算的难度。因此,我们通常考虑的是最坏的情况,因为最坏情况能够让我们知道程序运行时间的上限,能够避免意外的发生。

2. 实例分析

实例一:计算a的b次方

方法一:常规方法

# 方法一:用常规方法计算a的b次方
def exp1(a,b):
    ans = 1 #一次
    while (b>0):  #3b次
        ans *= a
        b -= 1
    return ans #一次

程序执行的步骤为:1 + 3b + 1 = 2 + 3b次

b = 300 , 执行次数:902;

b = 3000, 执行次数:90002;

b = 30000,执行次数,9000002;

可以发现,随着b的增长,2和3的作用越来越小,因为单单b就可以体现出函数的增长的上限。因此我们引入了Big O的概念:

Big O:upper limit to growth of function as the input gets large.

大 O:当问题规模变大时候对应的解决方法的增长上限

因此,方法一的时间复杂度为O(b).

方法二:递归方法

#方法二:递归方法求a的b次方
def exp2(a,b):
    if b == 1: #一次
        return a
    else:
        return a*exp2(a,b-1)  #2次,一次乘法,一次减法

首先我们假设时间为t(b),可以进行如下推导:

t(b)=3+t(b-1)

=3+3+t(b-2)

=...

=3k + t(b-k)

其中,b-k=1,代入,因为t(1)=2,所以,可得

t(b)=3b-1

因此,方法二的时间复杂度仍然为O(b)

方法三:根据b奇偶性的不同分别进行判断

a**b:

b为偶数:(a*a)**(b/2),规模减半

b为奇数:a*(a**(b-1))

#8.3 分类法求平方根
def exp3(a,b):
    if b == 1:
        return a
    if b%2 ==0:
        return exp3(a*a,b/2)
    else:
        return a*exp3(a,b-1)

可以简单计算出时间复杂度:

b为偶数: t(b) = 5 + t(b/2)

b为奇数:t(b) = 5 + t(b-1) = 10 + t(b-1/2)

也就是说,没经过两轮,规模减半,所以时间复杂度为O(logb)

实例2:时间复杂度为O(n²)的例子

这个例子很简单,不多说明

#8.4
def g(n): x=0
   for i in range(n):
      for j in range(m):
x += 1 return x

实例3:汉罗塔问题

主要介绍如何从递归角度来考虑汉罗塔问题

解题思路:

设三个圆盘的名称分别为为:fromstack(起始圆盘)、sparestack(空余圆盘)、tostack(目的圆盘)

如果个数为1,直接从fromstack移动到tostack

如果个数为n:

  1. 将n-1个圆盘移动到sparestack
  2. 将第n个圆盘移动到tostack
  3. 然后将n-1个圆盘移动到tostack

代码:

#8.4 用递归方法求解汉罗塔问题
def Towers(size,fromStack,toStack,spareStack):
    if size == 1:
        print(‘Move disk from ‘,fromStack,‘to‘,toStack)
    else:
        Towers(size-1,fromStack,spareStack,toStack)
        Towers(1,fromStack,toStack,spareStack)
        Towers(size-1,spareStack,toStack,fromStack)

该算法的时间复杂度为O(n²)

计算机科学及编程导论(8)算法的复杂度

时间: 2024-11-02 09:17:39

计算机科学及编程导论(8)算法的复杂度的相关文章

计算机科学及编程导论(7)数组及可变性、字典、伪代码,代码运行效率简介

1. 数组及可变性 当创建一个数组的时候,它将与一个对象进行绑定 L1 = [1, 2, 3] L2 = L1 L1[0] = 4 print(L2)#=>[4, 2, 3] L2 = L1 意味着L2与L1指向同一个对象,而L1[0]=4则改变了对象的值,所以最终L2的值也会改变,可以与下面这个例子进行比较 a = 1 #a指向对象1 b = a #b指向对象a a = 4 #此时a指向了对象4 print(b) #=>1,由于b依旧指向对象1,所以没有发生变化 2.字典 字典包括了以下几个

计算机科学及编程导论(3)迭代程序的设计与实现、遍历、元组

1. 迭代程序的设计:基础元素 迭代程序的实现,通常包括下了以下五个部分: 计数器(Count):用于标记循环的次数 初始化(Initiate):在循环外部进行初始化 正确的结束测试(Right End Test):在什么情况下结束通常与计数器(Count)密切相关 循环部分的代码块:该部分代码块通常包含了对计数器的改变 结束后程序应该做什么 2. 迭代程序的设计:流程图 在使用具体的代码实现之前,可以用流程图来组织程序. 举一个简单的例子,已经一个正整数的平方为X,要求这个正整数,可以设这个正

计算机科学及编程导论(5)浮点数和二分法

1. Python的数字类型 Python的数字类型分为两类:整型(int)以及浮点型(float). 对于Python来说,整型可以取无限大. Python的整型可以取任意精度 例如,可以输入2**1000次方,仍然会返回正确结果. Python的浮点类型按照IEE754标准,对于64位的计算机而言,表示成如下方式 1位:符号位 11位:指数位 52位:尾数位 这样总共可以表示17位长的精度,如果超过17位,Python就无法处理,比如 0.1**1000次方. 在教学视频中,如果输入 x =

计算机科学及编程导论(1)绪论

1. 课程介绍 这门课程适用于那些拥有很少或没有编程经验的学生,它致力于使学生理解计算机在解决问题中的作用,所用的编程语言为Python,共24个课时 2. 课程目标 计算思维.能够编写短小的代码 阅读代码.能够读懂他人的代码 理解计算.认识计算的能力与局限 具体应用.将科学的问题转化为具体的计算过程 3. 知识的种类 知识分为两大类:陈述性知识以及程序性知识 3.1 陈述性知识 陈述性知识,可以简单的理解为事实. ∵ √X = Y ∴ Y2 = X(当X ≥0 ) 虽然上述描述是正确的,但是却

计算机科学及编程导论(4)函数抽象与递归

position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位问题.所以当没有定义position属性时,并不说明该元素没有自己的位置,它会遵循默认显示为静态位置,在静态定位状态下无法通过坐标值(top,left,right,bottom)来改变它的位置. position:absolute(绝对定位) 当position属性定义为absolute时,元素会脱离文档流

计算机科学及编程导论学习笔记

不要频繁变换变量的类型 多用有意义的通俗易懂的变量名 python的raw_input的值都默认为字符串 “=”是用来赋值的,将左边的名字绑定到右边的值上去.因此比较的时候要用“==” if <测试语句> :

计算机科学及编程导论(2)Python语法基础:分支、条件卓揍尊作纵鬃

http://www.jiaoyou8.com/friends_diary/qingsiwen/0_0_0/view_0018942121_no_0_0.2015-01-31.html http://www.jiaoyou8.com/friends_diary/qingsiwen/0_0_0/view_0018942119_no_0_0.2015-01-31.html http://www.jiaoyou8.com/friends_diary/qingsiwen/0_0_0/view_00189

MIT公开课:计算机科学及编程导论 Python 笔记5 浮点数,逐次逼近法和二分法

Lecture5: Floating point number , successive refinement, finding roots 浮点数和二分法 3wschool 数字 >>> a = 2 ** 1000 >>> a 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251

计算机科学及编程导论:第一课

目标 1.学会用计算思维编写程序 think like a computer scientist 2.读懂别人的程序 3.了解计算的基本能力和局限 4.把科学问题转换成计算问题 什么是计算? 知识分为陈述性知识(是什么)和过程性知识(如何做,又称指令性知识,对推导过程的描述,如何判别) 如何用机械工艺实现这些步骤?  1.电子电路 (如计算器,属于固定程序计算机)   2.存储程序计算机(改变规则,可以赋予其一系列指令,让你执行) 语言的分类 三个维度:1.低级 VS 高级 2.广泛用途 VS