《算法图解》自学笔记

递归

递归函数

  • 递归条件 recursive case: 函数调用自己
  • 基线条件 base case: 避免无限循环
#求阶乘
def fact(x):
    if x == 1:
        return 1
    else:
        return x*fact(x-1)
#分别调用计算出 fact(3)、fact(2)、fact(1) return 1后 
#返回 2*fact(1) 再返回 3*fact(2) (fact(2)又为前一次的返回值)
#每个 fact 调用都有自己的 x 变量
#在一个函数调用中不能访问另一个 x 变量
print(fact(3))
#找出数组中最小的元素
def findsmallest(arr):
    smallest = arr[0]
    smallest_index = 0
    for i in range(1,len(arr)):
        if arr[i]<smallest:    
        #后面的每个数都跟第一个数比较
           smallest = arr[i]   
           #如果有更小的就返回更小数索引
           smallest_index = i
    return smallest_index

#对数组中元素从小到大排序

def selectionSort(arr):
    newArr = []    #数放到新列表中
    for i in range(len(arr)):
        smallest = findsmallest(arr)
        newArr.append(arr.pop(smallest))   
        #添加完最小的后从原列表 pop,再接着在结尾添加次小的
    return newArr
print(selectionSort([5,3,6,2,10]))

#复习一下sort 函数,直接修改原列表
answer = [5,3,6,2,10]
answer.sort()
print(answer)
#倒计时
def countdowm(i):
    print(i)
    if i <= 0:  #基线条件
        return
    else:       #递归条件
        countdowm(i-1)
countdowm(6)
#快速排序
def quicksort(array):
    if len(array) < 2:
        return array #基线条件:为空和只有一个元素时是有序的
    else:
        pivot = array[0]  #递归条件
        less = [i for i in array[1:] if i <= pivot] 
        #小于基准值的元素组成的子数组
        greater = [i for i in array[1:] if i > pivot]
        #大于基准值的元素组成的子数组
        return quicksort(less)+[pivot]+quicksort(greater)
print (quicksort([10,5,2,3]))

广度优先搜索(breadth-first search,BFS)

  • 队列 先进先出
  • 栈 后进先出
  • 搜索邻居时,创建一个数组用于记录检查过的人,将检查过的人标记,避免出现重复两人互为邻死循环。

狄克斯特拉算法 计算加权图中的最短路径

  1. 找出最短时间内前往的节点
  2. 检查是否有前往该节点邻居的更短路径,如果有,更新
  3. 重复,除了终点的所有节点
  4. 计算最终路径
  5. 不能用于包含负权边的图
infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
print(costs)   #{'a': 6, 'b': 2, 'fin': inf}

graph = {}  #储存各边的权重
graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}
print(graph)  #{'a': {'fin': 1}, 'b': {'a': 3, 'fin': 5}, 'fin': {}}

parents = {}   #储存父节点的散列表
parents['a'] = "start"
parents['b'] = "start"
parents['fin'] = None
print(parents)  #{'a': 'start', 'b': 'start', 'fin': None}

processed = [] #记录处理过的节点

#找出开销最小的节点
def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    for node in costs:  #遍历所有节点
        cost = costs[node]
        if cost < lowest_cost and node not in processed: #如果当前节点开销更低且未处理过
            lowest_cost = cost  #就视为开销最低节点
            lowest_cost_node = node
            return lowest_cost_node


node = find_lowest_cost_node(costs)  #在未处理的节点中找出开销最小的节点
while node is not None:      #while 循环在所有节点都被处理过后才结束
    cost = costs[node]
    neighbors = graph[node]
    for n in neighbors.keys():  #遍历当前节点所有邻居
        new_cost = cost + neighbors[n]
        if costs[n] > new_cost:
            costs[n] = new_cost
            parents[n] = node
    processed.append(node)
    node = find_lowest_cost_node(costs)

print(costs)   # {'a': 5, 'b': 2, 'fin': 7}
print(parents) # {'a': 'b', 'b': 'start', 'fin': 'a'}

贪婪算法
近似算法 寻找局部最优解,企图获得全局最优解

  • 并集 |
  • 交集&

动态规划
逐步计算最大价值,寻找最优解
每个子问题互不依赖(离散)

费曼算法(Feynman algorithm)
(1) 将问题写下来。
(2) 好好思考。
(3) 将答案写下来。

KNN 算法
余弦相似度计算角度而不是矢量距离 适合保守评价

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sink Arsenic

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值