首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 30个常用算法

Python 30个常用算法

作者头像
用户11081884
发布2026-07-20 18:39:48
发布2026-07-20 18:39:48
280
举报

一、基础数据结构与算法

算法

说明

时间复杂度

线性搜索

逐个比对

O(n)

二分查找

有序序列折半

O(log n)

选择排序

每次选最小

O(n²)

插入排序

增量构造有序区

O(n²)

归并排序

分治+合并

O(n log n)

1. 线性搜索

代码语言:javascript
复制
def linear_search(arr, target):
    for i, v in enumerate(arr):
        if v == target:
            return i
    return -1

print(linear_search([4, 2, 7, 1, 9], 7))      # → 2

2. 二分查找(迭代版)

代码语言:javascript
复制
def binary_search(arr, target):
    left, right = 0, len(arr) -1
    while left<= right:
        mid = (left+right) //2
        if arr[mid] == target:
            return mid
        elif arr[mid] <target:
            left = mid+1
        else:
            right = mid-1
    return -1

print(binary_search([1, 3, 5, 7, 9], 5))      # → 2

3. 选择排序

代码语言:javascript
复制
def selection_sort(arr):
    for i in range(len(arr)):
        min_i = i
        for j in range(i+1, len(arr)):
            if arr[j] <arr[min_i]:
                min_i = j
        arr[i], arr[min_i] = arr[min_i], arr[i]
    return arr

print(selection_sort([64, 25, 12, 22, 11]))  # → [11, 12, 22, 25, 64]

4. 插入排序

代码语言:javascript
复制
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i-1
        while j>= 0 and arr[j] >key:
            arr[j+1] = arr[j]
            j -= 1
        arr[j+1] = key
    return arr

print(insertion_sort([12, 11, 13, 5, 6]))    # → [5, 6, 11, 12, 13]

5. 归并排序

代码语言:javascript
复制
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) //2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    res, i, j = [], 0, 0
    while i<len(left) and j<len(right):
        if left[i] <right[j]:
            res.append(left[i]); i += 1
        else:
            res.append(right[j]); j += 1
    res.extend(left[i:]); res.extend(right[j:])
    return res

print(merge_sort([38, 27, 43, 3, 9, 82, 10]))  # → [3, 9, 10, 27, 38, 43, 82]

二、树与图

算法

说明

时间复杂度

前/中/后序遍历

DFS 递归

O(n)

BFS

队列层次遍历

O(V+E)

DFS

栈/递归深搜

O(V+E)

6-8. 二叉树三种遍历

代码语言:javascript
复制
class Node:
    def__init__(self, val):
        self.val, self.left, self.right = val, None, None

# 构造示例树
root = Node(1); root.left = Node(2); root.right = Node(3)
root.left.left = Node(4); root.left.right = Node(5)

def preorder(r):
    return [r.val] +preorder(r.left) +preorder(r.right)

def inorder(r):
    return inorder(r.left) + [r.val] +inorder(r.right)

def postorder(r):
    return postorder(r.left) +postorder(r.right) + [r.val]

print(preorder(root))   # → [1, 2, 4, 5, 3]
print(inorder(root))    # → [4, 2, 5, 1, 3]
print(postorder(root))  # → [4, 5, 2, 3, 1]

9. BFS(图)

代码语言:javascript
复制
from collections import deque

def bfs(graph, start):
    visited, queue = set(), deque([start])
    visited.add(start)
    while queue:
        v = queue.popleft()
        print(v, end=' ')
        for n in graph[v]:
            if n not in visited:
                visited.add(n); queue.append(n)

graph = {'A':['B','C'],'B':['A','D','E'],'C':['A','F'],'D':['B'],'E':['B','F'],'F':['C','E']}
bfs(graph, 'A')  # → A B C D E F

10. DFS(图)

代码语言:javascript
复制
def dfs(graph, start, visited=None):
    if visited is None: visited = set()
    visited.add(start)
    print(start, end=' ')
    for n in graph[start]:
        if n not in visited: dfs(graph, n, visited)

dfs(graph, 'A')  # → A B D E F C

三、高级图算法

算法

功能

复杂度

Dijkstra

单源最短路径

O((V+E) log V)

Floyd-Warshall

全源最短路径

O(V³)

Kruskal / Prim

最小生成树

O(E log V)

拓扑排序

检测有向环

O(V+E)

11. Dijkstra(堆优化)

代码语言:javascript
复制
import heapq

def dijkstra(graph, start):
    dist = {v: float('inf') for v in graph}
    dist[start] = 0
    heap = [(0, start)]
    while heap:
        d, u = heapq.heappop(heap)
        if d>dist[u]: continue
        for v, w in graph[u].items():
            nd = d+w
            if nd<dist[v]:
                dist[v] = nd
                heapq.heappush(heap, (nd, v))
    return dist

g = {'A':{'B':1,'C':4},'B':{'A':1,'C':2,'D':5},'C':{'A':4,'B':2,'D':1},'D':{'B':5,'C':1}}
print(dijkstra(g, 'A'))  # → {'A': 0, 'B': 1, 'C': 3, 'D': 4}

12. Floyd-Warshall

代码语言:javascript
复制
def floyd_warshall(g):
    n = len(g)
    dist = [[float('inf')]*n for _ in range(n)]
    for i in range(n): dist[i][i] = 0
    for u in g:
        for v, w in g[u].items(): dist[u][v] = w
    for k in range(n):
        for i in range(n):
            for j in range(n):
                dist[i][j] = min(dist[i][j], dist[i][k] +dist[k][j])
    return dist

g = {0:{1:3,2:6},1:{0:3,2:2},2:{0:6,1:2}}
print(floyd_warshall(g))  # → [[0, 3, 5], [3, 0, 2], [5, 2, 0]]

13. Kruskal(并查集实现)

代码语言:javascript
复制
class UnionFind:
    def __init__(self, n): self.p = list(range(n))
    def find(self, x):
        if self.p[x] != x: self.p[x] = self.find(self.p[x])
        return self.p[x]
    def union(self, x, y): self.p[self.find(y)] = self.find(x)

def kruskal(g):
    edges = [(w, u, v) for u in g for v, w in g[u].items()]
    edges.sort()
    uf, mst = UnionFind(len(g)), []
    for w, u, v in edges:
        if uf.find(u) != uf.find(v):
            uf.union(u, v); mst.append((u, v, w))
    return mst

g = {0:{1:10,2:6},1:{0:10,2:5},2:{0:6,1:5}}
print(kruskal(g))  # → [(1, 2, 5), (0, 2, 6)]

14. Prim(堆实现)

代码语言:javascript
复制
import heapq

def prim(g, start=0):
    visited, mst = {start}, []
    edges = [(w, start, v) for v, w in g[start].items()]
    heapq.heapify(edges)
    while edges:
        w, u, v = heapq.heappop(edges)
        if v not in visited:
            visited.add(v); mst.append((u, v, w))
            for v2, w2 in g[v].items():
                if v2 not in visited: heapq.heappush(edges, (w2, v, v2))
    return mst

print(prim(g))  # → [(0, 2, 6), (2, 1, 5)]

15. 拓扑排序(BFS)

代码语言:javascript
复制
from collections import deque, defaultdict

def topological_sort(graph):
    indeg = defaultdict(int)
    for u in graph:
        for v in graph[u]: indeg[v] += 1
    q = deque([u for u in graphifindeg[u] == 0])
    res = []
    while q:
        u = q.popleft(); res.append(u)
        for v in graph[u]:
            indeg[v] -= 1
            if indeg[v] == 0: q.append(v)
    return res if len(res) == len(graph) else None  # None 表示有环

g = {0:[1,2],1:[3],2:[3],3:[]}
print(topological_sort(g))  # → [0, 1, 2, 3]

四、动态规划

问题

状态转移

复杂度

斐波那契

dp[i]=dp[i-1]+dp[i-2]

O(n)

LCS

字符相等则+1

O(mn)

0-1 背包

选/不选

O(nW)

LIS

双层比较

O(n²)

编辑距离

插入/删除/替换

O(mn)

16. 斐波那契(递推)

代码语言:javascript
复制
def fib(n):
    if n<= 1: return n
    a, b = 0, 1
    for _ in range(2, n+1):
        a, b = b, a+b
    return b

print(fib(10))  # → 55

17. 最长公共子序列(LCS)

代码语言:javascript
复制
def lcs(a, b):
    m, n = len(a), len(b)
    dp = [[0] * (n+1) for _ in range(m+1)]
    for i in range(1, m+1):
        for j in range(1, n+1):
            if a[i-1] == b[j-1]:
                dp[i][j] = dp[i-1][j-1] +1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    return dp[m][n]

print(lcs("abcde", "ace"))  # → 3

18. 0-1 背包

代码语言:javascript
复制
def knapsack(w, v, cap):
    n = len(w)
    dp = [0] * (cap+1)
    for i in range(n):
        for c in range(cap, w[i] -1, -1):
            dp[c] = max(dp[c], dp[c-w[i]] +v[i])
    return dp[cap]

w = [1, 2, 3]; v = [6, 10, 12]; cap = 5
print(knapsack(w, v, cap))  # → 22

19. 最长递增子序列(LIS)

代码语言:javascript
复制
def lis(arr):
    if not arr: return0
    dp = [1] *len(arr)
    for i in range(1, len(arr)):
        for j in range(i):
            if arr[i] >arr[j]:
                dp[i] = max(dp[i], dp[j] +1)
    return max(dp)

print(lis([10, 9, 2, 5, 3, 7, 101, 18]))  # → 4

20. 编辑距离

代码语言:javascript
复制
def edit_distance(a, b):
    m, n = len(a), len(b)
    dp = [[0] * (n+1) for _ in range(m+1)]
    for i in range(m+1): dp[i][0] = i
    for j in range(n+1): dp[0][j] = j
    for i in range(1, m+1):
        for j in range(1, n+1):
            if a[i-1] == b[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = 1+min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
    return dp[m][n]

print(edit_distance("horse", "ros"))  # → 3

五、贪心算法

问题

贪心策略

复杂度

活动选择

最早结束

O(n log n)

霍夫曼编码

最小堆合并

O(n log n)

分数背包

单位价值降序

O(n log n)

找零

最大面额优先

O(n)

区间调度

最早结束

O(n log n)

21. 活动选择

代码语言:javascript
复制
def activity_selection(start, finish):
    acts = sorted(zip(start, finish), key=lambdax: x[1])
    res = [acts[0]]
    last = acts[0][1]
    for s, f in acts[1:]:
        if s>= last:
            res.append((s, f))
            last = f
    return res

s = [1, 3, 0, 5, 8, 5]; f = [2, 4, 6, 7, 9, 9]
print(activity_selection(s, f))  # → [(1, 2), (3, 4), (5, 7), (8, 9)]

22. 霍夫曼编码

代码语言:javascript
复制
import heapq
from collections import defaultdict

def huffman(freq):
    heap = [[w, [sym, ""]] for sym, w in freq.items()]
    heapq.heapify(heap)
    while len(heap) >1:
        lo = heapq.heappop(heap)
        hi = heapq.heappop(heap)
        for pair in lo[1:]: pair[1] = '0'+pair[1]
        for pair in hi[1:]: pair[1] = '1'+pair[1]
        heapq.heappush(heap, [lo[0] +hi[0]] +lo[1:] +hi[1:])
    return {sym: code for sym, code in heap[0][1:]}

freq = {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}
print(huffman(freq))  # → {'f': '0', 'c': '100', 'd': '101', 'a': '1100', 'b': '1101', 'e': '111'}

23. 分数背包

代码语言:javascript
复制
def fractional_knapsack(values, weights, capacity):
    items = sorted(zip(values, weights), key=lambdax: x[0]/x[1], reverse=True)
    total = 0.0
    for v, w in items:
        if capacity>= w:
            total += v; capacity -= w
        else:
            total += v*capacity/w; break
    return total

values = [60, 100, 120]; weights = [10, 20, 30]; capacity = 50
print(fractional_knapsack(values, weights, capacity))  # → 240.0

24. 找零(贪心版)

代码语言:javascript
复制
def coin_change(coins, amount):
    coins.sort(reverse=True)
    res = []
    for c in coins:
        while amount>= c:
            res.append(c); amount -= c
    return res if amount == 0elseNone

print(coin_change([1, 5, 10, 25], 63))  # → [25, 25, 10, 1, 1, 1]

25. 区间调度

代码语言:javascript
复制
def interval_scheduling(intervals):
    intervals.sort(key=lambdax: x[1])
    res, last_end = [], float('-inf')
    for s, e in intervals:
        if s>= last_end:
            res.append((s, e)); last_end = e
    return res

print(interval_scheduling([(1, 3), (2, 4), (3, 5), (6, 8)]))  # → [(1, 3), (3, 5), (6, 8)]

六、回溯算法

问题

思想

复杂度

全排列

交换/标记

O(n!)

组合总和

可选重复

O(2^target)

N 皇后

行+列+对角线剪枝

O(N!)

子集

选/不选

O(2^n)

数独

空格试填+剪枝

O(9^m)

26. 全排列(交换法)

代码语言:javascript
复制
def permute(nums):
    res = []
    def dfs(first=0):
        if first == len(nums):
            res.append(nums.copy()); return
        for i in range(first, len(nums)):
            nums[first], nums[i] = nums[i], nums[first]
            dfs(first+1)
            nums[first], nums[i] = nums[i], nums[first]
    dfs()
    return res

print(permute([1, 2, 3]))

27. 组合总和(可重复)

代码语言:javascript
复制
def combination_sum(candidates, target):
    res = []
    def dfs(remain, path, start):
        if remain == 0: res.append(path); return
        if remain<0: return
        for i in range(start, len(candidates)):
            dfs(remain-candidates[i], path+ [candidates[i]], i)
    dfs(target, [], 0)
    return res

print(combination_sum([2, 3, 6, 7], 7))  # → [[2, 2, 3], [7]]

28. N 皇后

代码语言:javascript
复制
def solve_n_queens(n):
    res, cols, diag1, diag2 = [], set(), set(), set()

    def dfs(row, path):
        if row == n:
            res.append(['.'*c+'Q'+'.'* (n-1-c) for c in path])
            return
        for c in range(n):
            d1, d2 = row-c, row+c
            if c in cols or d1 in diag1or d2 in diag2: continue
            cols.add(c); diag1.add(d1); diag2.add(d2)
            dfs(row+1, path+ [c])
            cols.remove(c); diag1.remove(d1); diag2.remove(d2)

    dfs(0, [])
    return res

print(len(solve_n_queens(4)))  # → 2 个合法解

29. 子集(选/不选)

代码语言:javascript
复制
def subsets(nums):
    res = []
    def dfs(path, i):
        if i == len(nums):
            res.append(path); return
        dfs(path+ [nums[i]], i+1)  # 选
        dfs(path, i+1)              # 不选
    dfs([], 0)
    return res

print(subsets([1, 2, 3]))

30. 数独求解

代码语言:javascript
复制
def solve_sudoku(board):
    def is_valid(r, c, num):
        for i in range(9):
            if board[r][i] == num or board[i][c] == num: return False
        br, bc = (r//3) *3, (c//3) *3
        for i in range(3):
            for j in range(3):
                if board[br+i][bc+j] == num: return False
        return True

    def dfs():
        for r in range(9):
            for c in range(9):
                if board[r][c] == '.':
                    for num in map(str, range(1, 10)):
                        if is_valid(r, c, num):
                            board[r][c] = num
                            if dfs(): return True
                            board[r][c] = '.'
                    return False
        return True

    dfs()
    return board

b = [
    ["5","3",".",".","7",".",".",".","."],
    ["6",".",".","1","9","5",".",".","."],
    [".","9","8",".",".",".",".","6","."],
    ["8",".",".",".","6",".",".",".","3"],
    ["4",".",".","8",".","3",".",".","1"],
    ["7",".",".",".","2",".",".",".","6"],
    [".","6",".",".",".",".","2","8","."],
    [".",".",".","4","1","9",".",".","5"],
    [".",".",".",".","8",".",".","7","9"]
]
solve_sudoku(b)
for row in b: print(row)  # 已填充完整棋盘

Python中30个常用算法,涵盖了基础数据结构、树与图算法、高级算法、动态规划、贪心算法和回溯算法等多个领域。每个算法都配有详细的代码示例和使用说明,帮助开发者快速掌握这些核心算法思想,掌握这些算法将显著提升你的编程能力和问题解决能力,为更高级的算法学习和应用打下坚实基础。

“无他,惟手熟尔”!有需要就用起来。

如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Nicholas与Pypi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、基础数据结构与算法
    • 1. 线性搜索
    • 2. 二分查找(迭代版)
    • 3. 选择排序
    • 4. 插入排序
    • 5. 归并排序
  • 二、树与图
    • 6-8. 二叉树三种遍历
    • 9. BFS(图)
    • 10. DFS(图)
  • 三、高级图算法
    • 11. Dijkstra(堆优化)
    • 12. Floyd-Warshall
    • 13. Kruskal(并查集实现)
    • 14. Prim(堆实现)
    • 15. 拓扑排序(BFS)
  • 四、动态规划
    • 16. 斐波那契(递推)
    • 17. 最长公共子序列(LCS)
    • 18. 0-1 背包
    • 19. 最长递增子序列(LIS)
    • 20. 编辑距离
  • 五、贪心算法
    • 21. 活动选择
    • 22. 霍夫曼编码
    • 23. 分数背包
    • 24. 找零(贪心版)
    • 25. 区间调度
  • 六、回溯算法
    • 26. 全排列(交换法)
    • 27. 组合总和(可重复)
    • 28. N 皇后
    • 29. 子集(选/不选)
    • 30. 数独求解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档