算法与数据结构:从基础到深入
1. 数组 (Array)
定义
- 一组连续内存空间存储的相同类型元素的集合。
- 特点:通过下标(索引)快速访问元素,但大小固定(静态数组)或可扩展(动态数组)。
核心操作
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| 访问元素 | O(1) | 通过索引直接访问(如arr[3]) |
| 插入元素 | O(n) | 需要移动后续元素 |
| 删除元素 | O(n) | 同上 |
| 查找元素 | O(n) | 遍历查找(无序数组) |
代码示例
# 创建数组
arr = [1, 2, 3, 4]# 访问元素
print(arr[0]) # 输出 1# 插入元素(在末尾添加)
arr.append(5) # O(1)(动态数组均摊时间)
arr.insert(2, 10) # O(n)(插入到中间)# 删除元素
arr.pop() # 删除末尾元素 O(1)
arr.pop(0) # 删除第一个元素 O(n)
应用场景
- 需要快速随机访问(如矩阵运算)
- 数据量已知或变化较小的场景
2. 链表 (Linked List)
定义
- 由节点组成的数据结构,每个节点包含数据和指向下一个节点的指针。
- 特点:内存非连续,插入/删除高效,但访问元素需要遍历。
类型
- 单链表:每个节点指向下一个节点。
- 双链表:节点同时指向前驱和后继。
- 循环链表:尾节点指向头节点。
核心操作
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| 访问元素 | O(n) | 从头节点开始遍历 |
| 插入/删除 | O(1) | 已知前驱节点时(如双链表) |
| 查找元素 | O(n) | 必须遍历 |
代码示例(单链表)
class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = next# 创建链表:1 -> 2 -> 3
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)# 插入节点(在节点2后插入4)
node = head.next
new_node = ListNode(4)
new_node.next = node.next
node.next = new_node # 链表变为1 -> 2 -> 4 -> 3# 删除节点(删除节点4)
node.next = node.next.next # 链表恢复为1 -> 2 -> 3
应用场景
- 频繁插入/删除的场景(如LRU缓存)
- 实现栈、队列等数据结构
3. 栈 (Stack)
定义
- 后进先出(LIFO)的线性结构。
- 核心操作:
push(入栈)、pop(出栈)、peek(查看栈顶)。
代码示例
# 用列表模拟栈
stack = []
stack.append(1) # push 1
stack.append(2) # push 2
top = stack[-1] # peek -> 2
stack.pop() # pop -> 2
应用场景
- 函数调用栈
- 括号匹配、表达式求值(如逆波兰表达式)
4. 队列 (Queue)
定义
- 先进先出(FIFO)的线性结构。
- 核心操作:
enqueue(入队)、dequeue(出队)。
代码示例
from collections import deque
queue = deque()
queue.append(1) # 入队
queue.append(2)
front = queue[0] # 查看队首
queue.popleft() # 出队 -> 1
变种队列
- 双端队列 (Deque):两端均可插入/删除。
- 优先队列 (Priority Queue):按优先级出队(通常用堆实现)。
应用场景
- 任务调度、消息队列
- BFS(广度优先搜索)
5. 哈希表 (Hash Table)
5.1 哈希表 概念
定义
- 通过键(Key)直接访问值(Value)的数据结构。
- 核心思想:哈希函数将键映射到存储位置。
冲突解决
- 开放寻址法:冲突时寻找下一个空槽。
- 链地址法:每个槽存储链表(如Python的字典)。
代码示例
# Python字典 即哈希表实现
hash_map = {}
hash_map["apple"] = 1 # 插入
hash_map["banana"] = 2
print(hash_map.get("apple")) # 获取 -> 1
del hash_map["banana"] # 删除
应用场景
- 快速查找(如数据库索引)
- 统计频率(如字母异位词分组)
5.2 链地址法(Chaining)
核心思想
- 每个数组的索引位置(称为“桶”)不再直接存储单个键值对,而是存储一个链表(或红黑树等其他数据结构)。
- 当多个键的哈希值冲突时,它们会被添加到同一个桶的链表中。
具体操作
- 插入键值对:
- 计算键的哈希值,找到对应桶。
- 如果桶为空,直接存入链表头节点。
- 如果桶不为空,遍历链表:
- 如果发现键已存在,更新值。
- 如果不存在,将新键值对添加到链表末尾(或头部)。
- 查找键值对:
- 计算键的哈希值,找到对应桶。
- 遍历链表,逐个比较键是否匹配。
代码示例(Python简化版)
class HashTable:def __init__(self, size=10):self.size = sizeself.table = [[] for _ in range(size)] # 每个桶是一个列表(模拟链表)def _hash(self, key):return hash(key) % self.size # 哈希函数def put(self, key, value):bucket_idx = self._hash(key)bucket = self.table[bucket_idx]# 遍历链表,检查是否已存在该键for i, (k, v) in enumerate(bucket):if k == key:bucket[i] = (key, value) # 更新键值对returnbucket.append((key, value)) # 添加新键值对def get(self, key):bucket_idx = self._hash(key)bucket = self.table[bucket_idx]for k, v in bucket:if k == key:return vreturn None # 未找到
为什么链地址法不会导致效率低下?
虽然链表需要遍历,但哈希表的设计目标是通过以下两点保证高效性:
(1) 哈希函数的均匀性
- 好的哈希函数会将键均匀分布到各个桶中,避免大量冲突。
- 例如,Python的哈希函数对字符串、整数等类型有优化,冲突概率极低。
(2) 负载因子(Load Factor)控制
- 负载因子 = 哈希表中元素数量 / 桶的数量。
- 当负载因子超过阈值(如0.75),哈希表会触发扩容(Rehashing):
- 创建一个更大的桶数组(例如翻倍)。
- 将所有键值对重新哈希到新桶中。
- 扩容后,冲突概率显著降低,链表长度保持较短(通常为0-2个节点)。
现代哈希表(如Java的HashMap)会进一步优化链地址法:
- 链表转红黑树(Java):当链表长度超过阈值(如8),将链表转换为红黑树,将查找时间从
O(n)优化为O(log n)。 - 动态扩容策略:根据负载因子智能调整桶的数量,平衡时间和空间。
5.3 开放地址法(Open Addressing)
核心思想
开放地址法的思想是,当发生冲突时,寻找另一个空的数组位置来存储冲突的元素。常见的解决方法有线性探测法、二次探测法和双重哈希法等。
具体实现
- 插入:当插入新元素时,计算哈希值,如果该位置已经被占用,就按照预定的探测策略(如线性探测)尝试查找下一个空的位置。
- 查找:查找时,先计算哈希值,如果当前位置的元素就是我们要查找的键,就直接返回值。如果当前位置不匹配,就根据探测策略继续查找其他位置,直到找到目标或确认该键不存在。
代码示例(Python简化版)
class HashTable:def __init__(self, size=10):self.size = sizeself.table = [None] * self.size # 每个桶直接存储键值对或标记def _hash(self, key):return hash(key) % self.sizedef _probe(self, start_idx):"""线性探测下一个可用位置"""idx = start_idxwhile True:if self.table[idx] is None or self.table[idx] == "DELETED":return idxidx = (idx + 1) % self.size # 回绕到数组开头if idx == start_idx: # 整个表已满raise Exception("Hash table is full")def put(self, key, value):start_idx = self._hash(key)idx = start_idx# 查找可插入的位置或更新现有键while True:if self.table[idx] is None or self.table[idx] == "DELETED":# 插入新键值对self.table[idx] = (key, value)returnelif self.table[idx][0] == key:# 键已存在,更新值self.table[idx] = (key, value)returnidx = (idx + 1) % self.size # 通过取余方式能够遍历整个数组if idx == start_idx:raise Exception("Hash table is full")def get(self, key):start_idx = self._hash(key)idx = start_idxwhile True:entry = self.table[idx]if entry is None:return None # 未找到elif entry != "DELETED" and entry[0] == key:return entry[1] # 返回找到的值idx = (idx + 1) % self.sizeif idx == start_idx:return None # 遍历完整个表未找到
6. 二叉树 (Binary Tree)
定义
- 每个节点最多有两个子节点(左子节点、右子节点)。
- 特殊类型:
- 二叉搜索树 (BST):左子树所有节点 < 根节点 < 右子树所有节点。
- 平衡二叉树(如AVL树、红黑树):通过旋转保持高度平衡。
遍历方式
| 遍历方式 | 顺序 |
|---|---|
| 前序遍历 | 根 -> 左 -> 右 |
| 中序遍历 | 左 -> 根 -> 右 |
| 后序遍历 | 左 -> 右 -> 根 |
| 层序遍历 | 按层级从上到下、从左到右 |
代码示例(二叉树节点)
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = right# 创建二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
应用场景
- 文件系统结构
- 表达式树(用于计算)
7. 堆 (Heap)
定义
- 一种完全二叉树,满足:
- 最大堆:父节点值 ≥ 子节点值。
- 最小堆:父节点值 ≤ 子节点值。
:::tip
完全二叉树是指除了最后一层外,其他层的节点都是 满的,并且最后一层的节点 尽可能靠左排列。
:::
核心操作
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| 插入元素 | O(log n) | 上浮调整(sift up) |
| 删除堆顶 | O(log n) | 下沉调整(sift down) |
代码示例(Python的 heapq 模块)
import heapq# 最小堆
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 2)
print(heapq.heappop(heap)) # 输出1
应用场景
- 优先队列
- Top K问题(如最大的K个元素)
8. 图 (Graph)
定义
- 由 顶点(Vertex) 和 边(Edge) 组成的非线性结构。
- 表示方式:
- 邻接矩阵:二维数组表示顶点连接关系。
- 邻接表:为每个顶点维护一个链表,记录其邻居。
常见算法
- 遍历:DFS(深度优先)、BFS(广度优先)
- 最短路径:Dijkstra(无负权边)、Bellman-Ford(含负权边)
- 最小生成树:Prim算法、Kruskal算法
代码示例(邻接表表示图)
# 使用字典表示邻接表
graph = {'A': ['B', 'C'],'B': ['D'],'C': ['E'],'D': [],'E': []
}# DFS遍历
def dfs(graph, node, visited):if node not in visited:print(node)visited.add(node)for neighbor in graph[node]:dfs(graph, neighbor, visited)dfs(graph, 'A', set()) # 输出A -> B -> D -> C -> E
应用场景
- 社交网络(顶点为用户,边为好友关系)
- 路径规划(如地图导航)
相关文章:
算法与数据结构:从基础到深入
1. 数组 (Array) 定义 一组连续内存空间存储的相同类型元素的集合。特点:通过下标(索引)快速访问元素,但大小固定(静态数组)或可扩展(动态数组)。 核心操作 操作时间复杂度说明访…...
基于千兆5G网关的5G急救车方案
伴随5G网络的全面建成,5G技术的低延时、高速率、广接入等优势,为各行各业都带来了新一轮技术升级。在医疗救援方面,救护车是链接病患与医院的重要纽带,得益于5G物联网的融合应用,救护车也快速向联网化、信息化、智能化…...
【C#】的WPF或是WinForm实现Ctrl+ 的快捷键组合使用
在C#中,无论是WPF还是WinForms应用程序,处理快捷键(例如 Ctrl )通常涉及检测键盘输入并执行相应的命令或方法。 WPF 实现 在WPF中,可以通过设置一个控件的 InputBindings 属性来绑定快捷键。 <Window x:Class&qu…...
c语言样式主题 清爽风格 代码色彩 keil风格 适合单片机开发GD32 STM32等 cursor或者vscode 的settings.json文件
c语言样式主题 清爽风格 代码色彩 keil风格 适合单片机开发GD32 STM32等 cursor或者vscode 的settings.json文件 如上图,是不是和keil mdk很相近。 代码色彩,简单,配合 // 设置工作台主题为 Visual Studio 2017 Light - C 主题使用…...
DeepSeek API 调用 - Spring Boot 实现
DeepSeek API 调用 - Spring Boot 实现 1. 项目依赖 在 pom.xml 中添加以下依赖: <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></depe…...
图数据库Neo4j面试内容整理-节点(Node)
在图数据库中,节点(Node)是图结构中的基本构建块,代表实体或对象。节点通常用于存储数据模型中的主要对象,比如人、商品、地点等。在图数据库中,节点是通过标签(Label)来分类的,并且可以包含属性(Property)来描述它们的详细信息。 1. 节点的组成<...
使用verilog 实现 cordic 算法 ----- 旋转模式
1-设计流程 ● 了解cordic 算法原理,公式,模式,伸缩因子,旋转方向等,推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现,注意…...
2.14寒假
这几天复习的搜索把之前做过的题目看了一下。 解析:int dx[5]{0,0,1,0,-1}; 和 int dy[5]{0,1,0,-1,0};:这两个数组用于表示上下左右四个方向的偏移量,方便在 DFS 中访问相邻的元素。o 和 p 分别表示当前搜索位置的行和列。边界条件判断&…...
基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)
基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)是语义通信(Semantic Communication, SemCom)的核心研究方向,它们旨在优化通信效率&#…...
DeepSeek R1本地部署教程
尽管许多卖课博主声称能轻松运行满血版DeepSeek R1,但满血版R1模型参数高达671B,仅模型文件就需要404GB存储空间,运行时更需要约1300GB显存。 对于没有卡的普通玩家来说,运行的条件苛刻,且门槛极高。基于此࿰…...
CEF132编译指南 MacOS 篇 - 获取 CEF 源码 (五)
1. 引言 在完成了所有必要工具的安装和配置之后,我们正式进入获取 CEF132 源码的阶段。对于 macOS 平台,CEF 的源码获取过程需要特别注意不同芯片架构(Intel 和 Apple Silicon)的区别以及版本管理。本篇将作为 CEF132 编译指南系…...
TypeScript装饰器 ------- 学习笔记分享
目录 一. 简介 二. 类装饰器 1. 基本语法 2. 应用举例 3. 关于返回值 4. 关于构造类型 5. 替换被装饰的类 三. 装饰器工厂 四. 装饰器组合 五. 属性装饰器 1. 基本语法 2. 关于属性遮蔽 3. 应用举例 六. 方法装饰器 1. 基本语法 2. 应用举例 七. 访问器装饰器 …...
FPGA实现UltraScale GTH光口视频转USB3.0传输,基于FT601+Aurora 8b/10b编解码架构,提供2套工程源码和技术支持
目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的 GT 高速接口解决方案本博已有的FPGA驱动USB通信方案 3、工程详细设计方案工程设计原理框图输入Sensor之-->OV5640摄像头动态彩条输入视频之-->ADV…...
蓝桥杯篇---实时时钟 DS1302
文章目录 前言特点简介1.低功耗2.时钟/日历功能3.32字节的额外RAM4.串行接口 DS1302 引脚说明1.VCC12.VCC23.GND4.CE5.I/O6.SCLK DS1302 寄存器1.秒寄存器2.分钟寄存器3.小时寄存器4.日寄存器5.月寄存器6.星期寄存器7.年寄存器8.控制寄存器 DS1302 与 IAP25F2K61S2 的连接1.CE连…...
C语言蓝桥杯1003: [编程入门]密码破译
要将"China"译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母. 例如,字母"A"后面第4个字母是"E"."E"代替"A"。因此,"China"应译…...
【MySQL在Centos 7环境安装】
文章目录 一. 卸载不必要的环境二. 检查系统安装包三. 卸载这些默认安装包四. 获取mysql官⽅yum源五. 安装mysql yum 源,对⽐前后yum源六. 看看能不能正常⼯作七. 安装mysql服务八. .查看配置⽂件和数据存储位置九. 启动服务并查看服务是否存在十. 登陆⽅法十一. 设…...
科技引领未来,中建海龙C-MiC 2.0技术树立模块化建筑新标杆
在建筑行业追求高效与品质的征程中,中建海龙科技有限公司(简称“中建海龙”)以其卓越的创新能力和强大的技术实力,不断书写着装配式建筑领域的新篇章。1 月 10 日,由深圳安居集团规划,中建海龙与中海建筑共…...
玩转观察者模式
文章目录 什么是观察者模式解决方案结构适用场景实现方式观察者模式优缺点优点:缺点:什么是观察者模式 观察者模式通俗点解释就是你在观察别人,别人有什么变化,你就做出什么调整。观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察…...
Baklib知识中台构建企业智能运营核心架构
内容概要 在数字化转型的浪潮中,企业对于知识的系统化管理需求日益迫切。Baklib作为新一代的知识中台,通过构建智能运营核心架构,为企业提供了一套从知识汇聚到场景化落地的完整解决方案。其核心价值在于将分散的知识资源整合为统一的资产池…...
Anaconda +Jupyter Notebook安装(2025最新版)
Anaconda安装(2025最新版) Anaconda简介安装1:下载anaconda安装包2: 安装anaconda3:配置环境变量4:检查是否安装成功5:更改镜像源6:更新包7:检查 Jupyter Notebook一.Jup…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
