欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

算法入门--Day1

程序员文章站 2022-04-10 20:59:28
第一块内容 算法的概念 定义化概念 算法就是一个解决问题时的一个计算过程 概念的理解 在算法的角度上理解程序:程序 = 数据结构 + 算法 数据结构:数据的储存(比如定义的列表...等等的变量) 算法:就是一个动态操作变量的过程 ——所以其实函数也属于算法,当然函数的定义只能解决一些非常简单的问题 ......

第一块内容

算法的概念

  定义化概念

  算法就是一个解决问题时的一个计算过程

  概念的理解

  在算法的角度上理解程序:程序 =  数据结构  +   算法

    数据结构:数据的储存(比如定义的列表...等等的变量)

    算法:就是一个动态操作变量的过程

      ——所以其实函数也属于算法,当然函数的定义只能解决一些非常简单的问题

      ——顺而言之,其实算法的表现形式,也是以函数的形式在表现的

时间复杂度

  估计算法运行效率和时间复杂度

  时间复杂度的引入

    算法入门--Day1

     问题1很好回答,当然是第一组代码的运行时间最短,但是用什么方式来体现呢?

  还需要引入一个生活中的实例,

    算法入门--Day1

  通过这个实例,很直观的能表述出什么呢?

  很明显,我们都知道,几毫秒<几秒<几分钟<几小时<几天/几星期/几个月<几年

  所以我们可以类比此实例,用一个能分清大小的式子来评估算法的运行效率:

  o(1)< o(logn)<o(n)<o(nlogn)<o(n²)<o(n²logn)<o(n³)

  而这个式子表达的是什么意思呢?如下说明:

  比如刚刚最初的print代码:

    算法入门--Day1

  其中o表示的就是大概的一个,同生活案例中的几,而括号中的内容则表示了此程序的规模

  而什么又算作一个规模呢?下例:

    算法入门--Day1

  类比之前所讲内容,我们可以很直观的得到如上图的结果,但是!这个结果是错误的!

     算法入门--Day1

  通过这样的答案我们也不难看出规模指的其实就是相同量级的程序,图中3所代指的规模

  并没有上升到等同于n的规模,而n的规模也并没有上升到n²的规模,所以用一个大概值来表示

  其中o的涵义也反映了这个时间复杂度的判定标准,即一个大概的值

  而logn有又什么涵义呢?下面仍然用一组实例说明:

    算法入门--Day1

  可见,当算法过程出现折半的时候,复杂度的式子中会出现logn。

  综上所说:如何简单快速的判断算法的复杂度

    1.确定问题规模——>n

    2.循环减半过程——>logn

    3.k层关于n的循环——>n^k

  这三点适用于绝大多数简单的情况,复杂情况则需要根据算法执行过程判断

 

 空间复杂度

   其表达方式与时间复杂度完全一样,

    算法入门--Day1

   对于空间换时间的理解:

    ——代码宁愿占用更多的内存,也要让它能实现的更快【硬件的问题都是小问题(不是对于我)】

 

递归

  递归有两个特点:一是调用自身,二是结束条件

  所以根据这两个条件我们先行对下面几个函数进行一下判断:

  算法入门--Day1

  

   有上图可知,func3和func4为递归正确调用的方法,但是打印输出的内容确不相同,我们用图来表示一下其运行过程,

  首先是func3

  算法入门--Day1

  执行过程如图,外层大框表示函数的调用,里面小框为print过程,然后反复如此,所以呢,我们看到的打印结果,以x=4

  为例:顺序为,4,3,2,1

  而func4,运行如下图:

  算法入门--Day1

  执行过程如图,外层大框表示函数的调用,里面小框为print过程,然后反复如此,这些与func3运行一直,唯一不同的就是打印

  代码的位置不同,所以呢根据 如箭头的运行程序打印的结果是:1,2,3

 

   上面两个函数的方法其实就是递归描述的一种思维方式,那么递归思想又是从何 而来的呢?

  算法入门--Day1

 

   其实是根据这样一则故事而来,也被称之为汉诺塔问题,我们以3个圆盘为例解析一下此问题,

  算法入门--Day1 算法入门--Day1  

  算法入门--Day1 算法入门--Day1

  算法入门--Day1 算法入门--Day1

  算法入门--Day1

  那么如果是n个圆盘呢?其实我们可以根据上图总结出一定的规律,其实整个过程主要就分为了三步,

  将第n个盘子看做一部分,前n-1个盘子看做一部分,整个过程其实就是,默认三根木棍分别由a、b、c表示

  首先将前n-1个盘子,由a经过c移动到b,

  然后将第n个盘子,由a移动到c,

  最后在前前n-1个盘子,由b经过a移动到c,这样就完成了整个过程,这也引入了我们python算法中的汉诺塔算法:

  

def hanoi(n,a,b,c):
    # n表示n个盘子
    # a,b,c则表示了三根木棍
    if n>0:
        hanoi(n-1,a,c,b) # 将前n-1由a经过c移动到b
        print('moving from %s to %s'%(a,c))  # 将n由a移动到c
        hanoi(n-1,b,a,c)  # 将前n-1有b经过a移动到c

hanoi(3,"a","b","c")

  由此我们得到了汉诺塔移动次数的递推式,

  算法入门--Day1

  也就是两个n-1次的移动,加上1次移动,n-1次是前n-1个圆盘的,1次是最大圆盘的