python算法模板大全

BFS模板

from collections import deque
graph = graph
start = start
visited = set()  # 储存已经访问过的节点
queue = deque([start])  # 创建一个队列并将起点加入其中
visited.add(start)  # 将起点标记为已访问
 
while queue:  # 当队列不为空时执行循环
    cur = queue.popleft()  # 取出队首元素
    print(cur)  # 访问当前节点
    if cur in graph:
        for neighbor in graph[cur]:  # 遍历当前节点的所有相邻节点
            if neighbor not in visited:  # 如果相邻节点未被访问过
                queue.append(neighbor)  # 将其加入队列尾部
                visited.add(neighbor)  # 并将其标记为已访问过

DFS模板

visited = []
def dfs(node):
    """深度优先搜索遍历树/图的函数"""
    # 先将当前节点标记为已访问,并进行相关操作
    print(node)
    visited.append(node)
    # 针对当前节点的所有邻居/子节点进行递归
    if node not in graph:
        return
    else:
        for neighbor in graph[node]:
            # 判断该节点是否被访问过,如果没被访问过就递归访问它
            if neighbor not in visited:
                dfs(neighbor)
# 在主程序中调用dfs函数并传入起始节点
dfs(node)

DP模板

N = '列数'
M = '行数'
dp = [[0] * (N+1) for _ in range(M+1)]
for i in range(1, M+1):
    for j in range(1, N+1):
        if '判断条件':
            dp[i][j] = max(dp[i-1][j], dp[i][j-1])
        else:
            dp[i][j] = xxxx

01背包

def test():
    weight = '物品重量列表'
    value = '物品价值列表'
    bag_weight = '背包容量'
	# 初始化: 全为0
    dp = [0] * (bag_weight + 1)
    # 先遍历物品, 再遍历背包容量
    for i in range(len(weight)):
        for j in range(bag_weight, weight[i] - 1, -1):
            # 递归公式
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
    print(dp)
test()

并查集模板

def root(x):
    # 查找x的根节点
    if p[x]!=x:
        # 如果发现x的根节点不是自己
        p[x]=root(p[x])
        # 递归找x的根节点,直到找到最原始的根节点为止
    return p[x]
    # 返回根节点(根节点上面没根节点,自己是根节点)
def union(x,y):
    # 合并两个结点
    if root(x)!=root(y):
        # 如果根节点不同
        p[root(x)]=root(y)
        # 根节点x指向根节点y

Dijkstra模板

class Dijkstra:
    def __init__(self, graph, start, goal):
        self.graph = graph  # 邻接表
        self.start = start  # 起点
        self.goal = goal
        
        self.open_list = {}  # open 表
        self.closed_list = {}  # closed 表
        
        self.open_list[start] = 0.0  # 将起点放入 open_list 中
        
        self.parent = {start: None}  # 存储节点的父子关系 键为子节点, 值为父节点
        self.min_dis = None  # 最短路径的长度
        
    def shortest_path(self):
        while True:
            if self.open_list is None:
                print('搜索失败, 结束')
                break
                
            distance, min_node = min(zip(self.open_list.values(), self.open_list.keys()))
            # 取出距离最小的节点
            self.open_list.pop(min_node)  # 将其从 open_list 中去除
            
            self.closed_list[min_node] = distance  # 将节点加入 closed_list 中
            
            if min_node == self.goal:  # 如果节点为终点
                self.min_dis = distance
                shortest_path = [self.goal]  # 记录从终点回溯的路径
                father_node = self.parent[self.goal]
                while father_node != self.start:
                    shortest_path.append(father_node)
                    father_node = self.parent[father_node]
                shortest_path.append(self.start)
                print(shortest_path[::-1])  # 逆序
                print('最短路径的长度为: %s' % str(self.min_dis))  # 输出
                print('找到最短路径, 结束')
                return shortest_path[::-1], self.min_dis  # 返回最短路径和最短路径长度
            
            for node in self.graph[min_node].keys():  # 遍历当前节点的邻接节点
                if node not in self.closed_list.keys():  # 邻接节点不在 closed_list 中
                    if node in self.open_list.keys():  # 如果节点在 open_list 中
                        if self.graph[min_node][node] + distance < self.open_list[node]:
                            self.open_list[node] = distance + self.graph[min_node][node]
                            # 更新节点的值
                            self.parent[node] = min_node  # 更新继承关系
                    else:  # 如果节点不在 open_list 中
                        self.open_list[node] = distance + self.graph[min_node][node]
                        # 计算节点的值, 并加入 open_list 中
                        self.parent[node] = min_node  # 更新继承关系
                            
if __name__ == '__main__':
    graph = {'1': {'2': 2, '4': 1},
         '2': {'4': 3, '5': 11},
         '3': {'1': 4, '6': 5},
         '4': {'3': 2, '6': 8, '7': 4, '5': 2},
         '5': {'7': 6},
         '7': {'6': 1}}
    start = '1'
    goal = '6'
    dijk = Dijkstra(graph, start, goal)
    dijk.shortest_path()

Floyd模板

from sys import setrecursionlimit
setrecursionlimit = 10e10

def Floyd():
    n = len(graph)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                if graph[i][k] + graph[k][j] < graph[i][j]:
                    graph[i][j] = graph[i][k] + graph[k][j]
                    parents[i][j] = parents[k][j]  # 更新父节点

# 输出
def return_path(i,j):
    if i != j: return_path(i,parents[i][j])
    print(j, end = '-->')

# 数据定义
# Data [u,v,cost]
datas = [
    [0, 1, 2],
    [0, 2, 6],
    [0, 3, 4],
    [1, 2, 3],
    [2, 0, 7],
    [2, 3, 1],
    [3, 0, 5],
    [3, 2, 12]
]
n = 4

# 构图
graph=[[(lambda x: 0 if x[0] == x[1] else float('inf'))([i,j]) for j in range(n)] for i in range(n)]
parents=[[i] * n for i in range(4)]  # 关键点: i-->j 的父节点初始化都为i
for u,v,c in datas:
    graph[u][v] = c  # 因为是有向图, 边权只赋给graph[u][v]
#     graph[v][u] = c  # 如果是无向图, 要加上这条

# 主函数
Floyd()

# 输出
print('Costs:')
for row in graph:
    for e in row:
        print('∞' if e == float('inf') else e, end='\t')
    print()

print('\nPath:')
for i in range(n):
    for j in range(n):
        print('Path(%d-->%d): ' % (i,j),end='')
        return_path(i,j)
        print(' cost:',graph[i][j])

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值