python 数据结构与算法

在这篇博客中,我们将探讨一些高级的 Python 编程示例,包括快速排序、归并排序、堆排序、深度优先搜索、广度优先搜索、最短路径算法、最小生成树、拓扑排序、Trie 树和动态规划。

示例 1:快速排序

步骤

  1. 定义一个函数 quick_sort,对一个列表进行快速排序。
  2. 选择一个基准元素,将列表分为小于、等于和大于基准元素的三个部分。
  3. 递归地对左右部分进行排序,并合并结果。

代码

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

# Example usage
arr = [3, 6, 8, 10, 1, 2, 1]
print("Quick Sort:", quick_sort(arr))

 

代码解析

  1. def quick_sort(arr):定义快速排序函数。
  2. pivot = arr[len(arr) // 2]:选择基准元素。
  3. left, middle, right:将列表分为小于、等于和大于基准元素的三个部分。
  4. return quick_sort(left) + middle + quick_sort(right):递归地对左右部分进行排序,并合并结果。

运行结果

Quick Sort: [1, 1, 2, 3, 6, 8, 10]

示例 2:归并排序

步骤

  1. 定义一个函数 merge_sort,对一个列表进行归并排序。
  2. 将列表分为左右两部分,递归地对左右部分进行排序。
  3. 定义一个函数 merge,合并两个有序列表。

代码

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):
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])
    return result

# Example usage
arr = [3, 6, 8, 10, 1, 2, 1]
print("Merge Sort:", merge_sort(arr))

代码解析

  1. def merge_sort(arr):定义归并排序函数。
  2. mid = len(arr) // 2:将列表分为左右两部分。
  3. left = merge_sort(arr[:mid]):递归地对左部分进行排序。
  4. right = merge_sort(arr[mid:]):递归地对右部分进行排序。
  5. return merge(left, right):合并两个有序列表。

运行结果

Merge Sort: [1, 1, 2, 3, 6, 8, 10]

 

示例 3:堆排序

步骤

  1. 定义一个函数 heapify,将列表调整为堆。
  2. 定义一个函数 heap_sort,对一个列表进行堆排序。
  3. 构建最大堆,并将最大元素移到末尾,重复此过程。

代码

 

def heapify(arr, n, i):
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2

    if left < n and arr[i] < arr[left]:
        largest = left

    if right < n and arr[largest] < arr[right]:
        largest = right

    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

def heap_sort(arr):
    n = len(arr)
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)

# Example usage
arr = [3, 6, 8, 10, 1, 2, 1]
heap_sort(arr)
print("Heap Sort:", arr)

 

代码解析

  1. def heapify(arr, n, i):定义堆调整函数。
  2. def heap_sort(arr):定义堆排序函数。
  3. for i in range(n // 2 - 1, -1, -1):构建最大堆。
  4. for i in range(n - 1, 0, -1):将最大元素移到末尾,重复此过程。

运行结果

Heap Sort: [1, 1, 2, 3, 6, 8, 10]

示例 4:深度优先搜索

步骤

  1. 定义一个函数 dfs,实现图的深度优先搜索算法。
  2. 使用递归遍历图的节点。

代码

def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    visited.add(start)
    print(start, end=' ')
    for neighbor in graph[start] - visited:
        dfs(graph, neighbor, visited)

# Example usage
graph = {
    'A': {'B', 'C'},
    'B': {'A', 'D', 'E'},
    'C': {'A', 'F'},
    'D': {'B'},
    'E': {'B', 'F'},
    'F': {'C', 'E'}
}
print("DFS:", end=' ')
dfs(graph, 'A')

 

代码解析

  1. def dfs(graph, start, visited=None):定义深度优先搜索函数。
  2. visited.add(start):将当前节点标记为已访问。
  3. for neighbor in graph[start] - visited:遍历未访问的邻居节点。
  4. dfs(graph, neighbor, visited):递归地进行深度优先搜索。

运行结果

DFS: A B D E F C 

示例 5:广度优先搜索

步骤

  1. 导入 deque 模块。
  2. 定义一个函数 bfs,实现图的广度优先搜索算法。
  3. 使用队列遍历图的节点。

代码

from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])
    visited.add(start)
    while queue:
        vertex = queue.popleft()
        print(vertex, end=' ')
        for neighbor in graph[vertex] - visited:
            visited.add(neighbor)
            queue.append(neighbor)

# Example usage
graph = {
    'A': {'B', 'C'},
    'B': {'A', 'D', 'E'},
    'C': {'A', 'F'},
    'D': {'B'},
    'E': {'B', 'F'},
    'F': {'C', 'E'}
}
print("\nBFS:", end=' ')
bfs(graph, 'A')

 

代码解析

  1. from collections import deque:导入 deque 模块。
  2. def bfs(graph, start):定义广度优先搜索函数。
  3. queue = deque([start]):初始化队列。
  4. while queue:遍历队列中的节点。
  5. for neighbor in graph[vertex] - visited:遍历未访问的邻居节点。

运行结果

BFS: A B C D E F 

 

示例 6:最短路径算法

步骤

  1. 导入 heapq 模块。
  2. 定义一个函数 dijkstra,实现 Dijkstra 算法计算图的最短路径。
  3. 使用优先队列维护最短路径。

代码

import heapq

def dijkstra(graph, start):
    distances = {vertex: float('infinity') for vertex in graph}
    distances[start] = 0
    pq = [(0, start)]

    while pq:
        current_distance, current_vertex = heapq.heappop(pq)

        if current_distance > distances[current_vertex]:
            continue

        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight

            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))

    return distances

# Example usage
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'D': 2, 'E': 7},
    'C': {'A': 4, 'F': 5},
    'D': {'B': 2},
    'E': {'B': 7, 'F': 3},
    'F': {'C': 5, 'E': 3}
}
print("Dijkstra Shortest Path:", dijkstra(graph, 'A'))

代码解析

  1. import heapq:导入 heapq 模块。
  2. def dijkstra(graph, start):定义 Dijkstra 算法函数。
  3. distances = {vertex: float(‘infinity’) for vertex in graph}:初始化所有节点的距离为无穷大。
  4. distances[start] = 0:设置起始节点的距离为 0。
  5. pq = [(0, start)]:初始化优先队列。
  6. while pq:遍历优先队列中的节点。
  7. current_distance, current_vertex = heapq.heappop(pq):弹出优先队列中的最小距离节点。
  8. for neighbor, weight in graph[current_vertex].items():遍历当前节点的邻居节点。
  9. distance = current_distance + weight:计算邻居节点的距离。
  10. if distance < distances[neighbor]:如果计算的距离小于已知的最短距离,更新距离并将邻居节点加入优先队列。

 

运行结果

# Example usage
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'D': 2, 'E': 7},
    'C': {'A': 4, 'F': 5},
    'D': {'B': 2},
    'E': {'B': 7, 'F': 3},
    'F': {'C': 5, 'E': 3}
}
print("Dijkstra Shortest Path:", dijkstra(graph, 'A'))

Dijkstra Shortest Path: {'A': 0, 'B': 1, 'C': 4, 'D': 3, 'E': 8, 'F': 7}

示例 7:最小生成树

步骤

  1. 导入 heapq 模块。
  2. 定义一个函数 prim,实现 Prim 算法计算图的最小生成树。
  3. 使用优先队列维护最小生成树的边。

代码

 

import heapq

def prim(graph, start):
    mst = []
    visited = set()
    edges = [(cost, start, to) for to, cost in graph[start].items()]
    heapq.heapify(edges)
    visited.add(start)

    while edges:
        cost, frm, to = heapq.heappop(edges)
        if to not in visited:
            visited.add(to)
            mst.append((frm, to, cost))
            for neighbor, cost in graph[to].items():
                if neighbor not in visited:
                    heapq.heappush(edges, (cost, to, neighbor))

    return mst

# Example usage
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'D': 2, 'E': 7},
    'C': {'A': 4, 'F': 5},
    'D': {'B': 2},
    'E': {'B': 7, 'F': 3},
    'F': {'C': 5, 'E': 3}
}
print("Prim's Minimum Spanning Tree:", prim(graph, 'A'))

代码解析

  1. import heapq:导入 heapq 模块。
  2. def prim(graph, start):定义 Prim 算法函数。
  3. mst = []:初始化最小生成树的边列表。
  4. visited = set():初始化已访问节点集合。
  5. edges = [(cost, start, to) for to, cost in graph[start].items()]:初始化优先队列。
  6. heapq.heapify(edges):将边列表转换为优先队列。
  7. while edges:遍历优先队列中的边。
  8. cost, frm, to = heapq.heappop(edges):弹出优先队列中的最小边。
  9. if to not in visited:如果目标节点未访问,加入最小生成树并更新优先队列。

运行结果

Prim's Minimum Spanning Tree: [('A', 'B', 1), ('B', 'D', 2), ('A', 'C', 4), ('C', 'F', 5), ('F', 'E', 3)]

示例 8:拓扑排序

步骤

  1. 导入 defaultdict 和 deque 模块。
  2. 定义一个函数 topological_sort,实现拓扑排序算法。
  3. 使用队列维护入度为 0 的节点。

代码

from collections import defaultdict, deque

def topological_sort(graph):
    indegree = {node: 0 for node in graph}
    for node in graph:
        for neighbor in graph[node]:
            indegree[neighbor] += 1

    zero_indegree_queue = deque([node for node in indegree if indegree[node] == 0])
    topo_order = []

    while zero_indegree_queue:
        node = zero_indegree_queue.popleft()
        topo_order.append(node)
        for neighbor in graph[node]:
            indegree[neighbor] -= 1
            if indegree[neighbor] == 0:
                zero_indegree_queue.append(neighbor)

    if len(topo_order) == len(graph):
        return topo_order
    else:
        return []

# Example usage
graph = {
    'A': ['B', 'C'],
    'B': ['D'],
    'C': ['D', 'E'],
    'D': ['E'],
    'E': []
}
print("Topological Order:", topological_sort(graph))

 

 

代码解析

  1. from collections import defaultdict, deque:导入 defaultdict 和 deque 模块。
  2. def topological_sort(graph):定义拓扑排序函数。
  3. indegree = {node: 0 for node in graph}:初始化所有节点的入度为 0。
  4. for node in graph:遍历图中的节点,计算每个节点的入度。
  5. zero_indegree_queue = deque([node for node in indegree if indegree[node] == 0]):初始化入度为 0 的节点队列。
  6. while zero_indegree_queue:遍历队列中的节点。
  7. node = zero_indegree_queue.popleft():弹出队列中的节点。
  8. for neighbor in graph[node]:遍历当前节点的邻居节点,更新入度。

运行结果

Topological Order: ['A', 'B', 'C', 'D', 'E']

示例 9:Trie 树

步骤

  1. 定义 Trie 树节点类 TrieNode
  2. 定义 Trie 树类 Trie,实现插入和搜索操作。

代码

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end_of_word = False

class Trie:
    def __init__(self):
        self.root = TrieNode()

    def insert(self, word):
        current_node = self.root
        for char in word:
            if char not in current_node.children:
                current_node.children[char] = TrieNode()
            current_node = current_node.children[char]
        current_node.is_end_of_word = True

    def search(self, word):
        current_node = self.root
        for char in word:
            if char not in current_node.children:
                return False
            current_node = current_node.children[char]
        return current_node.is_end_of_word

# Example usage
trie = Trie()
trie.insert("apple")
trie.insert("app")
print("Search 'apple':", trie.search("apple"))  # 输出True
print("Search 'app':", trie.search("app"))      # 输出True
print("Search 'banana':", trie.search("banana"))  # 输出False

 

代码解析

  1. class TrieNode:定义 Trie 树节点类。
  2. class Trie:定义 Trie 树类。
  3. def insert(self, word):定义插入单词的方法。
  4. def search(self, word):定义搜索单词的方法。

运行结果

Search 'apple': True
Search 'app': True
Search 'banana': False

示例 10:动态规划

步骤

  1. 定义一个函数 knapsack,使用动态规划解决背包问题。
  2. 初始化动态规划表 dp
  3. 递归地计算每个子问题的最优解。

代码

def knapsack(weights, values, capacity):
    n = len(weights)
    dp = [[0] * (capacity + 1) for _ in range(n + 1)]
    
    for i in range(1, n + 1):
        for w in range(1, capacity + 1):
            if weights[i - 1] > w:
                dp[i][w] = dp[i - 1][w]
            else:
                dp[i][w] = max(dp[i - 1][w], values[i - 1] + dp[i - 1][w - weights[i - 1]])
    
    return dp[n][capacity]

# Example usage
weights = [1, 2, 3, 4, 5]
values = [10, 20, 30, 40, 50]
capacity = 7
print("Maximum value in knapsack:", knapsack(weights, values, capacity))

 

代码解析

  1. def knapsack(weights, values, capacity):定义背包问题的动态规划函数。
  2. n = len(weights):获取物品数量。
  3. dp = [[0] * (capacity + 1) for _ in range(n + 1)]:初始化动态规划表 dp
  4. for i in range(1, n + 1):遍历所有物品。
  5. for w in range(1, capacity + 1):遍历所有可能的容量。
  6. if weights[i - 1] > w:如果当前物品的重量大于当前容量,不能选择该物品。
  7. dp[i][w] = dp[i - 1][w]:不选择当前物品,继承上一个状态的值。
  8. else:如果当前物品的重量小于等于当前容量,可以选择该物品。
  9. dp[i][w] = max(dp[i - 1][w], values[i - 1] + dp[i - 1][w - weights[i - 1]]):选择当前物品,更新动态规划表。

运行结果

# Example usage
weights = [1, 2, 3, 4, 5]
values = [10, 20, 30, 40, 50]
capacity = 7
print("Maximum value in knapsack:", knapsack(weights, values, capacity))
Maximum value in knapsack: 90

总结

通过这篇博客文章,你学会了如何使用 Python 实现一些高级的编程示例,包括快速排序、归并排序、堆排序、深度优先搜索、广度优先搜索、最短路径算法、最小生成树、拓扑排序、Trie 树和动态规划。我们逐步讲解了代码的实现,包括步骤、代码解析和运行结果。你可以根据需要修改和扩展这些示例,以实现更多的功能。

其他文章推荐

相关类型推荐

  • 深入理解 Python 数据结构与算法
  • Python 高级编程技巧
  • Python 算法与数据结构实战

希望这个详细的讲解对你有所帮助!如果你有任何问题或需要进一步的帮助,请随时告诉我。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LIY若依

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

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

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

打赏作者

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

抵扣说明:

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

余额充值