1.算法

1.1时间复杂度

时间复杂度:用来评估算法运行效率的一个式子!

算法_第1张图片
算法_第2张图片

由于print()一次与print多次,执行时间相差很小,所以时间复杂度统一为O(1)。
相对于循环来说,中间执行的代码时间相对来说很小,所以只要是循环,时间复杂度只与循环的次数有关。

算法_第3张图片

小节:
1.时间复杂度是用来估计算法运行时间的一个式子。
2.一般来说,时间复杂度高的算法比复杂度低的算法慢。
3.常见的时间复杂度效率
O(1)
快速判断算法复杂度规模(适用于大多数情况):
1.没有循环,为O(1)
2.循环n次,为O(n)
3.k层循环,为n^k
4.循环减半,为log2^n

复杂情况,根据算法执行过程判断

1.2空间复杂度

空间复杂度:用来评估算法内存占用大小的式子。
1.算法只是使用了一些变量,空间复杂度为O(1)。
2.算法使用了长度为n的一维列表,空间复杂度为O(n)。
3.算法使用了m行n列的二维列表,空间复杂度为O(m*n)

在实际编程中,我们都会以空间来换取时间,即使占用内存,也要争取速度。

2.递归

2.1常见例子

算法_第4张图片

2.2汉诺塔问题

要求把所有圆盘从A上挪到另一个柱子上
小圆盘不能放在大圆盘上
一次只能移动一个盘子

算法_第5张图片
算法_第6张图片
算法_第7张图片

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
def hanio(n,a,b,c):
    if n>0:
        hanio(n-1,a,c,b)
        print("from %s to %s"%(a,c))
        hanio(n-1,b,a,c)
hanio(3,"A", "B", "C")

算法_第8张图片

汉诺塔移动次数的递推式:h(x)=2h(x-1)+1

2.列表查找

2.1顺序查找

顺序查找:也叫线性查找,从列表第一个元素开始,顺序搜索,直到找到元素或搜索到最后一个元素。
时间复杂度为O(n)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
def search(li,val):
    for index, v in enumerate(li):
        if v == val:
            return index
    return None
index = search([1,2,4,5,9,3], 4)

print(index)  # 2

2.2二分法查找

⼆分查找:⼜叫折半查找,从有序列表的初始候选区li[0:n]开
始,通过对待查找的值与候选区中间值的⽐较,可以使候选
区减少⼀半。

时间复杂度:O(logn)

算法_第9张图片

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def search(li,val):
    length = len(li)
    min = 0
    max = length - 1
    while min <= max:
        mid = (min + max)//2
        if li[mid] == val:
            return mid
        elif li[mid] > val:
            max = mid -1
        elif li[mid] < val:
            min = mid + 1
    return None

index = search([1,2,4,5,9], 4)

print(index)  # 2

3.列表排序

排序:将一组"无序"的列表调整为"有序"列表
有升序与降序排列
python内置排序函数:sort()

算法_第10张图片

3.1冒泡排序

列表每相邻的数,如果前面比后面的大,则交换这两个数。
一趟排序完成后,最后一个是最大的,无序区域减少一个数。有序区域增加一个数。

时间复杂度为O(n^2)
def bubble(li):
    for i in range(len(li)-1):
        for j in range(len(li)-i-1):
            if li[j]>li[j+1]:
                li[j],li[j+1]=li[j+1],li[j]
        print(li)
    return li
res = bubble([2,4,5,1,7,6])
print(res)

算法_第11张图片

冒泡排序优化:
如果冒泡排序中的一趟排序没有发生交还,则说明列表已经有序,可以直接结束算法。

def bubble(li):
    for i in range(len(li)-1):
        exchange = False
        for j in range(len(li)-i-1):
            if li[j]>li[j+1]:
                li[j],li[j+1]=li[j+1],li[j]
                exchange = True
        print("----------",li)
        if not exchange:
            break
    return li

res = bubble([1,2,3,4,5,6])
print(res)

3.2选择排序

一趟排序记录最小的数,放在第一个位置。
再一次排序记录无序区最小的数,放到第二个位置。

算法关键点:有序区和无序区,无序区最小数的位置。
时间复杂度:O(n^2)
def select(li):
    for i in range(len(li)-1):
        min_index = i
        for j in range(i+1, len(li)):
            if li[j]

算法_第12张图片

3.3插入排序

时间复杂度为O(n^2)

算法_第13张图片
算法_第14张图片

def insert(li):
    for i in range(1,len(li)):
        tmp = li[i]  # 这是拿到的牌
        j = i - 1  # 这是手里的牌
        while j>=0 and tmp

算法_第15张图片