算法与数据结构:从基础到深入
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…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
