当前位置: 首页 > news >正文

Python数据结构综合应用:实战案例与练习

Python数据结构综合应用:实战案例与练习

一、数据结构回顾

本周学习的核心数据结构及其Python实现方式如下:

数据结构特点Python实现示例
列表(List)有序,可修改,动态数组my_list = [1, 2, 3]
元组(Tuple)有序,不可修改my_tuple = (1, 2, 3)
栈(Stack)LIFO(后进先出)使用列表的append()pop()
队列(Queue)FIFO(先进先出)使用collections.deque
双向链表快速插入/删除自定义节点类实现
哈希表O(1)时间复杂度查找字典dict类型
二叉搜索树左子树值 < 根 < 右子树值自定义树节点类
图(Graph)节点与边的集合字典表示邻接表

二、实战案例解析

案例1:LRU缓存实现

需求场景

设计一个最近最少使用缓存,当容量达到上限时淘汰最久未使用的数据。

实现方案
class DLinkedNode:
    def __init__(self, key=0, value=0):
        self.key = key
        self.value = value
        self.prev = None
        self.next = None

class LRUCache:
    def __init__(self, capacity: int):
        self.cache = {}
        self.capacity = capacity
        self.head, self.tail = DLinkedNode(), DLinkedNode()
        self.head.next = self.tail
        self.tail.prev = self.head

    def _add_node(self, node):
        node.prev = self.head
        node.next = self.head.next
        self.head.next.prev = node
        self.head.next = node

    def _remove_node(self, node):
        prev = node.prev
        next = node.next
        prev.next = next
        next.prev = prev

    def _move_to_head(self, node):
        self._remove_node(node)
        self._add_node(node)

    def get(self, key: int) -> int:
        if key not in self.cache:
            return -1
        node = self.cache[key]
        self._move_to_head(node)
        return node.value

    def put(self, key: int, value: int) -> None:
        if key in self.cache:
            node = self.cache[key]
            node.value = value
            self._move_to_head(node)
        else:
            if len(self.cache) >= self.capacity:
                last = self.tail.prev
                self._remove_node(last)
                del self.cache[last.key]
            new_node = DLinkedNode(key, value)
            self.cache[key] = new_node
            self._add_node(new_node)
关键设计
  • 哈希表:快速定位节点位置
  • 双向链表:维护访问顺序,头节点存放最近访问元素

案例2:Dijkstra最短路径算法

算法步骤
  1. 初始化距离字典,起点距离为0,其他为无穷大
  2. 使用优先队列存储未处理的节点
  3. 每次取出距离最小的节点
  4. 更新相邻节点的最短距离
Python实现
import heapq

def dijkstra(graph, start):
    distances = {vertex: float('infinity') for vertex in graph}
    distances[start] = 0
    pq = [(0, start)]
    
    while pq:
        current_dist, current_vertex = heapq.heappop(pq)
        
        if current_dist > distances[current_vertex]:
            continue
            
        for neighbor, weight in graph[current_vertex].items():
            distance = current_dist + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))
    
    return distances

# 示例图结构(邻接表)
graph = {
    'A': {'B': 6, 'D': 1},
    'B': {'A': 6, 'C': 5},
    'C': {'B': 5, 'D': 8, 'E': 4},
    'D': {'A': 1, 'C': 8, 'E': 3},
    'E': {'C': 4, 'D': 3}
}

print(dijkstra(graph, 'A'))  # 输出各节点到A的最短距离

三、综合练习题

1. 无序数组转二叉搜索树

class TreeNode:
    def __init__(self, val=0):
        self.val = val
        self.left = None
        self.right = None

def sorted_array_to_bst(nums):
    if not nums:
        return None
    
    mid = len(nums) // 2
    root = TreeNode(nums[mid])
    root.left = sorted_array_to_bst(nums[:mid])
    root.right = sorted_array_to_bst(nums[mid+1:])
    
    return root

# 使用示例
unsorted = [3, 1, 4, 5, 2]
sorted_arr = sorted(unsorted)
bst_root = sorted_array_to_bst(sorted_arr)

2. 有效括号表达式验证

def is_valid_expression(s: str) -> bool:
    stack = []
    brackets = {')': '(', ']': '[', '}': '{'}
    
    for char in s:
        if char in brackets.values():
            stack.append(char)
        elif char in brackets:
            if not stack or stack[-1] != brackets[char]:
                return False
            stack.pop()
    
    return not stack and any(c in '+*-/' for c in s)  # 确保包含运算符

print(is_valid_expression("(a+b)*c"))  # True
print(is_valid_expression("((a+b))"))  # False(缺少运算符)

3. 图中所有路径查找

def find_all_paths(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return [path]
    if start not in graph:
        return []
    paths = []
    for node in graph[start]:
        if node not in path:
            newpaths = find_all_paths(graph, node, end, path)
            for p in newpaths:
                paths.append(p)
    return paths

# 示例图结构
graph = {
    'A': ['B', 'C'],
    'B': ['D'],
    'C': ['D'],
    'D': ['E'],
    'E': []
}

print(find_all_paths(graph, 'A', 'E'))
# 输出:[['A', 'B', 'D', 'E'], ['A', 'C', 'D', 'E']]

四、总结提升

  1. 数据结构选择原则

    • 需要快速查找 → 哈希表
    • 需要维护顺序 → 链表/队列
    • 需要层级关系 → 树结构
    • 需要复杂关联 → 图结构
  2. 算法优化方向

    • 空间换时间(如LRU缓存)
    • 使用合适的数据结构加速操作
    • 递归与迭代的合理选择
  3. 调试技巧

    • 对于树/图问题,先手动绘制结构图
    • 使用print语句输出中间状态
    • 编写单元测试验证边界条件

建议将每个案例手写实现一遍,并通过LeetCode平台(146-LRU缓存、743-网络延迟时间等)进行强化练习。

相关文章:

  • keycloak - 开发环境的配置持久化
  • C++继承
  • springboot博客系统详解与实现(后端实现)
  • 《论湖仓一体架构及其应用》审题技巧 - 系统架构设计师
  • https:原理
  • C++复习专题——泛型编程(模版),包括模版的全特化和偏特化
  • 29.C++多态 2 (重载,重定义(隐藏),重写 三者的区别)
  • git常用命令(时常更新)
  • 医疗影像分割中的半监督学习实践:从算法原理到CT/MRI实战
  • MybatisPlus-扩展功能-枚举处理器
  • 【linux配置】 修改内核网络参数
  • Linux之loop设备(Loop Devices in Linux)
  • 冯诺依曼体系结构和操作系统
  • 逆向pyinstaller打包的exe软件,获取python源码(4)
  • Vue2+OpenLayers实现右键菜单功能(提供Gitee源码)
  • 【OMCI实践】ONT上线过程的omci消息(六)
  • 2、并行和并发有什么区别【中高频】
  • Linux | YUM / RPM 常用命令
  • CSDN 博客:CC++ 内存管理详解
  • 2.部署kafka:9092
  • 网站宣传的好处/网页设计培训学校
  • 郑州个人网站开发/百度平台我的订单
  • 互联网公司网站建设/长沙seo霜天博客
  • asp.net网站开发实例教程pdf/seo专员招聘
  • 网站优化关键词公司/web成品网站源码免费
  • 网站制作学校要的/网络营销方法有哪些