重学数据结构与算法(1)-从斐波那契数列了解算法

281 阅读4分钟

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

为什么要学习数据结构与算法

程序员干了三年了,最近感觉自己遇到了一个瓶颈,只能做一些表面的工作,例如写一点脚本,框架里面写一些增删改查的操作,调用一些包,调用一些API,以及做一些运维的工作,想了解语言及其相关框架的源码的时候非常吃力,或者在准备做一些复杂的工作(轮子)的时候不确定到底怎么做才能做到更好,很迷茫,深感自己的底层知识不足,还有自己的知识面很广但是不深,所以想乘着自己脑袋还没生锈来学习数据结构与算法,自己之前没有认真系统学习这方面的知识,自己一直知道这块的内容很重要,一直都把它放在后面在考虑,但是现在觉悟了,哈哈,这些基础的东西要乘早学好才能更加快速地了解学习后面的日新月异的知识啊,不能本末倒置,浮沙筑高台~

重学计划

先从简单的开始,先学习简单的常用的经典数据结构。使用什么编程语言呢?自己熟悉Python,Php,Go。自己也想尝试一下使用Java语言。当然并不是完全按Java来,看心情吧。当然数据结构与算法其实与编程语言无关,主要是一种思想。当然并不是照着百度来的知识或者哪本书中的东西来重新讲一遍,其中还会有自己的思考,还会把自己学到的知识拿出来讲一讲,还有自己亲身经历的故事~

现在开始

斐波那契数列

最初了解算法的时候当然是自己用Python计算斐波那契数列第N个的值,现在我们来重温一下斐波那契数列就是数列从第3项开始,每一项都等于前两项之和。

我们来看一下使用Python 来计算斐波那契数列第N位的值

递归法:

递归的方法,通俗来说就是自己调用自己,自己再调用自己,自动再调用自己,直到调用到最后返回,返回后再返回,返回后再返。。。当然这个调用深度是有限制的,太深了会报错。Python可以使用以下代码设置函数递归调用的深度:

import sys
sys.setrecursionlimit(1000000)

使用递归方法计算斐波那契函数列第N项的值:

import time
def fib(n):
    if n<=1:
        return n
    else:
        return fib(n-1)+fib(n-2)
​
start_time = time.time()
print(fib(35))
end_time = time.time()
print("函数执行时间:%s秒"%(end_time-start_time))

输出:

9227465
函数执行时间:3.583667516708374秒

简单循环:

初学者经常用的方法

def fib(n):
    if n<=1:
        return n
    n1 = 0
    n2 = 1
    for i in range(n-1):
        res = n1+n2 
        n1 = n2     #随着循环不断更新n1和n2的值
        n2 = res
    return res
start_time = time.time()
print(fib(35))
end_time = time.time()
print("函数执行时间:%s秒"%(end_time-start_time))

输出:

9227465
函数执行时间:0.0秒

可以看的出来使用递归的方法计算斐波那契数列的速度比简单循环计算的方法慢。代码越短可见的性能不见得比代码长的性能差呀,哈哈。

由此可见时间复杂度是评估算法好坏的重要标准。

时间复杂度

时间复杂度简单来说就是代码执行的时间,通常来说都是估算的时间。除了时间复杂度还有空间复杂度,空间复杂度指的是代码在运行过程中使用的临时内存空间,一个算法的优劣主要从算法的执行时间和所需要的临时内存空间的大小,关于空间复杂度我们留在后面再说。常用大O表示法来描述复杂度,它表示的是数据规模n对应的复杂度。复杂度可以通俗地说就是数据随着函数参数变大或者代码输入成员变多,其执行的时间变化曲线越陡峭那么复杂度就越高。

总结

今天就就开一个简单的小头,接下来计划循序渐进地说一说我重新学习数据结构与算法的路程。按照管理这系列文章会尽量通俗,哈哈,希望大家指出其中不足,相互进步。