算法入门--Day1

第一块内容

算法的概念

  定义化概念

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

  概念的理解

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

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

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

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

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

时间复杂度

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

  时间复杂度的引入

    《算法入门--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次是最大圆盘的  

 

    原文作者:功夫熊猫、阿辉
    原文地址: https://www.cnblogs.com/pandahui/p/11051451.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞