python数据结构和算法

数据结构和算法基本概念

算法是什么?

  • 算法是一系列解决问题的清晰指令,是计算机处理信息的本质!
  • 算法是独立存在的一种 解决问题的方法和思想!

解题的四步骤

  1. 分析需求
  2. 设计算法
  3. 代码实现
  4. 验证结果

例题
如果 a + b + c = 1000 , 且 a 2 + b 2 = c 2 ( a , b , c 为自然数 ) , 如何求所有的 a 、 b 、 c 可能的组合? 如果a+b+c=1000,且a^2+b^2=c^2(a,b,c为自然数),\\如何求所有的a、b、c可能的组合? 如果a+b+c=1000,a2+b2=c2(a,b,c为自然数)如何求所有的abc可能的组合?

  1. 分析需求

    找出所有a、b、c满足上述条件的组合

  2. 设计算法

    尝试a、b、c的所有的组合,判断每个组合是否满足上述两个条件,如果满足输出,否则继续判断下面的组合(枚举法)

  3. 代码实现

    # @Author  :泰敢人辣
    # Date     :2023/7/20 10:35
    import time
    s_time = time.time()
    for a in range(0,1001):
        for b in range(0,1001):
            for c in range (0,1001):
                if a + b + c == 1000 and a ** 2 +b ** 2 == c ** 2:
                    print(f'符合条件的组合为{a}{b}{c}')
    e_time  = time.time()
    print(f'程序执行了{s_time-e_time}')
    #输出结果如下
    '''
    符合条件的组合为0、500、500
    符合条件的组合为200、375、425
    符合条件的组合为375、200、425
    符合条件的组合为500、0、500
    程序执行了-68.64588284492493
    '''
    
  4. 验证结果

    显然使用枚举法进行一亿次的计算是可以得到结果的

    但是用时一分多钟,效率低下,故这种方法不可取,需要设计更为精妙的算法!

算法的特性

  • 输入项:算法具有0个或多个输入
  • 输出项:算法至少有1个输出
  • 有穷性:算法必须能在有限个步骤后终止,并且需要在可接受的时间内
  • 准确性:算法的每一步骤必须有确切的定义
  • 可行性:算法的每一步都是可行的

时间复杂度!!!

基于上面的例题代码:
在这里插入图片描述

框中的表达式是否需要知道每一个c的值?仔细想一想显然是吗,没有必要的吧!

反过来想一下,如果满足条件的c必然满足上面的等式,即:
c = 1000 − a − b c=1000-a-b c=1000ab
此时我们只用两个遍历即可

# @Author  :泰敢人辣
# Date     :2023/7/20 10:35
import time
s_time = time.time()

for a in range(0,1001):
    for b in range(0,1001):
        c = 1000 - a -b
        if a ** 2 +b ** 2 == c ** 2:
            print(f'符合条件的组合为{a}{b}{c}')


e_time  = time.time()
print(f'程序执行了{s_time-e_time}')

'''代码运行结果如下'''
'''
符合条件的组合为0、500、500
符合条件的组合为200、375、425
符合条件的组合为375、200、425
符合条件的组合为500、0、500
程序执行了-0.48239660263061523
'''

可以很明显的看到只用了不到1秒的时间就运行结束!!!

引入时间复杂度

对于程序的运行时间每次可能都会不一样,显然我们用运行时间来判定算法程序的好坏显然是不明智的!

程序运行的时间不一样,但是程序运行的步骤是一样子的!故我们可以用步骤的多少来描述算法

定义 时间频度 为程序运行的步骤,用T表示

for a in range(0,1001):
    for b in range(0,1001):
        for c in range (0,1001):
            if a + b + c == 1000 and a ** 2 +b ** 2 == c ** 2:
                print(f'符合条件的组合为{a}{b}{c}')

计算上述代码的时间频度:
T = 1000 × 1000 × 1000 × 2 T = 1000\times1000\times1000\times2 T=1000×1000×1000×2
问题的数据规模(n)发生变化时,时间频度T也会跟着变化,其通式为:
T = n 3 × 2 T=n^3\times2 T=n3×2

时间复杂度的定义及其简单计算

定义时间复杂度(渐进时间复杂度),描述随着问题的数据规模增长,算法的时间频度的增长趋势。记作:
O ( F ( n )) 其中 F ( n )时 T ( n )的渐进函数 O(F(n))\\其中F(n)时T(n)的渐进函数 OFn))其中Fn)时Tn)的渐进函数

在时间频度T的通式中,当n趋向于无穷大的时候,谁的值最大,谁就是时间复杂度!!!

例如:
T = n 3 × 2 其中的时间复杂度为: O ( n 3 ) T=n^3\times2\\其中的时间复杂度为:O(n^3) T=n3×2其中的时间复杂度为:On3

计算时的注意点

  • 计算时,往往只关注时间频度中的最高次项其他次要项和常数项忽略
  • 顺序结构,时间复杂度按加法来计算
  • 循环结构,时间复杂度按乘法来计算
  • 分支结构,时间复杂度取最大值
  • 没有特殊说明时,算法的时间复杂度都是指最坏的时间复杂度

常见的时间复杂度

时间频度举例非正式术语
12O(1)常数阶
2n+3O(n)线性阶
3n2 + 2n + 1O(n2)平方阶
5log2n+20O(logn)对数阶
2n+3nlog2n+19O(nlogn)nlogn阶
6n3+2n2+3n+4O(n3)立方阶
2nO(2n)指数阶
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

列表字典常用操作的时间复杂度

列表中添加元素的方法

a = []
#方法1
a += [1]   
'''
方法1等同于   a.extend([1])
'''
#方法二
a = a + 1
'''
方法二每次执行的时候都会重新创建内存地址   特别慢
'''

列表常用操作的时间复杂度

在这里插入图片描述

字典常用操作的时间复杂度

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TAGRENLA

您的打赏是我创作的动力,谢谢!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值