跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python算法

6 种常用自定义数据结构设计与实现技巧

哈希映射、双向链表、树状数组、LRU 缓存、并查集和跳表六种常见自定义数据结构。通过访问分析、设计技巧及 Python 代码示例,阐述了各结构的适用场景与性能特点。同时总结了包括选择合适结构、避免冗余、分层设计等在内的十大设计原则,助力开发者优化系统性能与可维护性。

利刃发布于 2026/3/28更新于 2026/9/1075 浏览
6 种常用自定义数据结构设计与实现技巧

1. 哈希映射(Hash Map)

简介

哈希映射是一种基于哈希函数的数据结构,提供高效的键值存储。

访问分析
操作平均时间复杂度最坏时间复杂度
插入O(1)O(n)
删除O(1)O(n)
搜索O(1)O(n)
设计技巧
  1. 选择合适的哈希函数,避免冲突。
  2. 使用链地址法或开放寻址法解决哈希冲突。
  3. 动态扩展哈希表,避免性能下降。
代码示例
class HashMap:
    def __init__(self, size=100):
        self.size = size
        self.table = [[] for _ in range(size)]

    def _hash(self, key):
        return hash(key) % self.size

    def insert(self, key, value):
        index = self._hash(key)
        for pair in self.table[index]:
            if pair[0] == key:
                pair[1] = value
                return
        self.table[index].append([key, value])

    def get(self, key):
        index = self._hash(key)
        for pair in self.table[index]:
            if pair[0] == key:
                return pair[1]
        return None

    def remove(self, key):
        index = self._hash(key)
        self.table[index] = [pair for pair in self.table[index] if pair[0] != key]

2. 双向链表(Doubly Linked List)

在这里插入图片描述

简介

双向链表是链表的一种扩展,每个节点包含前后两个指针。

访问分析
操作时间复杂度
插入O(1)
删除O(1)
搜索O(n)
设计技巧
  1. 使用哨兵节点,减少边界条件判断。
  2. 支持双向遍历,提高操作灵活性。
代码示例
class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None

class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = self.tail = new_node
        else:
            self.tail.next = new_node
            new_node.prev = self.tail
            self.tail = new_node

    def remove(self, data):
        cur = self.head
        while cur:
            if cur.data == data:
                if cur.prev:
                    cur.prev.next = cur.next
                if cur.next:
                    cur.next.prev = cur.prev
                if cur == self.head:
                    self.head = cur.next
                if cur == self.tail:
                    self.tail = cur.prev
                break
            cur = cur.next

3. 树状数组(Fenwick Tree)

在这里插入图片描述

简介

用于处理前缀和查询,常用于动态数据统计。

访问分析
操作时间复杂度
更新O(log n)
查询前缀和O(log n)
代码示例
class FenwickTree:
    def __init__(self, size):
        self.size = size
        self.tree = [0] * (size + 1)

    def update(self, index, value):
        while index <= self.size:
            self.tree[index] += value
            index += index & -index

    def query(self, index):
        sum_val = 0
        while index > 0:
            sum_val += self.tree[index]
            index -= index & -index
        return sum_val

4. LRU 缓存(Least Recently Used Cache)

在这里插入图片描述

简介

用于管理有限缓存,最少使用的项被移除。

访问分析
操作时间复杂度
插入/访问O(1)
代码示例
from collections import OrderedDict

class LRUCache:
    def __init__(self, capacity):
        self.cache = OrderedDict()
        self.capacity = capacity

    def get(self, key):
        if key not in self.cache:
            return -1
        self.cache.move_to_end(key)
        return self.cache[key]

    def put(self, key, value):
        if key in self.cache:
            self.cache.move_to_end(key)
        elif len(self.cache) >= self.capacity:
            self.cache.popitem(last=False)
        self.cache[key] = value

5. 并查集(Disjoint Set)

在这里插入图片描述

简介

用于动态连通性问题,如网络连接。

访问分析
操作时间复杂度
合并O(α(n))
查询O(α(n))
代码示例
class DisjointSet:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [1] * n

    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y):
        root_x = self.find(x)
        root_y = self.find(y)
        if root_x != root_y:
            if self.rank[root_x] > self.rank[root_y]:
                self.parent[root_y] = root_x
            else:
                self.parent[root_x] = root_y
                if self.rank[root_x] == self.rank[root_y]:
                    self.rank[root_y] += 1

6. 跳表(Skip List)

简介

用于有序数据的高效查询,替代平衡树。

访问分析
操作时间复杂度
插入O(log n)
删除O(log n)
查询O(log n)

数据结构设计技巧

在进行数据结构设计时,有几个技巧可以帮助提高系统的效率、可维护性和扩展性。以下是一些常用的技巧:

1. 选择合适的数据结构
  • 根据操作的类型选择:例如,若要频繁插入和删除元素,选择链表或双端队列;若要进行快速查找、插入和删除,哈希表或平衡二叉搜索树可能更适合。
  • 考虑时间复杂度:选择能最小化操作时间复杂度的数据结构,如哈希表的查找时间是 O(1),而数组是 O(n)。
  • 空间优化:如果内存有限,考虑压缩数据结构或使用位图等节省空间的数据结构。
2. 尽量避免冗余数据
  • 规范化:尽量避免重复存储相同的信息,可以通过规范化设计将冗余数据分散到不同的数据表或数据结构中。
  • 压缩存储:使用如位域、前缀树、哈夫曼编码等方法对数据进行压缩,减少存储空间。
3. 分层设计
  • 将数据结构设计分层,确保不同的功能模块数据结构独立,并且可以相互协作。比如,数据库系统中,索引结构、存储结构和缓存结构通常会分开设计。
4. 考虑缓存和预取
  • 数据访问的效率在现代计算机系统中通常受缓存局部性影响,可以考虑如何使数据结构适应缓存,例如通过顺序存储、分页等手段减少缓存未命中。
5. 使用设计模式
  • 工厂模式:用于创建特定数据结构的实例,可以提高代码的灵活性和可维护性。
  • 策略模式:用于不同算法的数据结构选择,例如,在不同的查询场景下选择不同的搜索树结构。
  • 代理模式:为数据结构设计添加一个代理层,实现延迟加载等功能。
6. 考虑数据的增长
  • 在设计数据结构时,要考虑数据的扩展性。比如,栈和队列在处理动态数据时,通常可以通过链表实现动态扩展,避免固定容量限制。
7. 优化查询和插入操作
  • 索引优化:比如,数据库中的 B 树或 B+ 树索引设计可以大大提高查询效率。
  • 哈希化:在适用场景下,使用哈希表可以大幅提升查找效率。
8. 避免过度设计
  • 数据结构设计要根据需求进行优化,避免为了解决极少出现的边界情况而设计复杂的数据结构。应当在保证性能的前提下,尽量简化设计。
9. 延迟计算
  • 对于复杂的数据结构,可以采用延迟计算的策略,直到真正需要数据时再进行计算。例如,懒加载模式可以减少不必要的数据处理。
10. 持久化和序列化
  • 在设计持久化存储时,选择合适的序列化机制(如 JSON、Protobuf、Thrift 等),能够方便数据的保存和恢复。

通过合理运用这些设计技巧,可以帮助你在构建系统时优化性能、提高系统的可维护性和可扩展性。

目录

  1. 1. 哈希映射(Hash Map)
  2. 简介
  3. 访问分析
  4. 设计技巧
  5. 代码示例
  6. 2. 双向链表(Doubly Linked List)
  7. 简介
  8. 访问分析
  9. 设计技巧
  10. 代码示例
  11. 3. 树状数组(Fenwick Tree)
  12. 简介
  13. 访问分析
  14. 代码示例
  15. 4. LRU 缓存(Least Recently Used Cache)
  16. 简介
  17. 访问分析
  18. 代码示例
  19. 5. 并查集(Disjoint Set)
  20. 简介
  21. 访问分析
  22. 代码示例
  23. 6. 跳表(Skip List)
  24. 简介
  25. 访问分析
  26. 数据结构设计技巧
  27. 1. 选择合适的数据结构
  28. 2. 尽量避免冗余数据
  29. 3. 分层设计
  30. 4. 考虑缓存和预取
  31. 5. 使用设计模式
  32. 6. 考虑数据的增长
  33. 7. 优化查询和插入操作
  34. 8. 避免过度设计
  35. 9. 延迟计算
  36. 10. 持久化和序列化

更多推荐文章

查看全部
  • 算法:双指针法详解(上)
  • 基于 GeoTools 和 SpringBoot 的省域驾车最快路线生成实践
  • API、REST API、RESTful API 与 Web Service 的区别
  • 基于 Q-learning 的无人机三维路径规划算法原理与 MATLAB 实现
  • Altera USB-Blaster 驱动安装与 FPGA 下载调试指南
  • JSON-java CDL转换终极指南:快速掌握逗号分隔列表与JSONArray互转技巧
  • MCP AI Copilot 考试冲刺指南:7 天关键准备与核心考点
  • Web 安全实战:Robots.txt 协议原理与利用防御
  • 医疗AI新范式:数理模型重构传统大模型面临的挑战
  • Python 中可迭代与不可迭代对象的区分与应用
  • 利用 AI 自动生成符合 xxxxxl19d18–19 规范的 Python 项目结构
  • 位运算算法专题:判断字符唯一性、丢失数字与两数之和等
  • 双指针实战:移动零与复写零算法解析
  • AIGC 核心概念解析:从原理到应用与未来趋势
  • ESP32 小智 AI 机器人语音对话系统设计与云端部署
  • Python 反爬虫实战:逆向 + 解密 + 绕过技术详解
  • Stable Diffusion 3.5 FP8 模型架构解析与优化技巧
  • 数据库迁移 TCO 分析:MySQL 替代隐性成本与工具链实测
  • Web 前端基础:HTML 核心语法与常用标签
  • 前端面试复盘:场景题与架构思维的重要性

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online