谈谈常见的数据结构(如数组、链表、栈、队列、哈希表、树、图)及其应用场景

一、数组(Array)

定义:连续存储相同类型数据的线性结构,支持随机访问。
应用场景:列表渲染、数据缓存、算法处理
代码示例

// 数组基本操作
const arr = [1, 2, 3, 4];
arr.push(5); // O(1) 平均时间复杂度
arr.pop();  // O(1)
arr.shift();// O(n) 不推荐高频使用
arr.unshift(0); // O(n)// 数组遍历优化
// 推荐写法(减少属性查找)
for (let i = 0, len = arr.length; i < len; i++) {console.log(arr[i]);
}// 二维数组初始化
const matrix = Array.from({ length: 3 }, () => new Array(3).fill(0));

使用建议

  1. 优先使用 push/pop 替代 shift/unshift
  2. 大数据量时避免频繁操作数组头部
  3. 遍历数组使用 for 循环而非 forEach 可提高性能
  4. 多维数组建议使用 Array.from 初始化

注意事项

  • 警惕数组越界访问
  • 避免使用稀疏数组(会影响性能)
  • 注意数组原型链方法的副作用(如 sort 会改变原数组)

二、链表(Linked List)

定义:由节点组成的链式结构,节点包含值和指向下一个节点的指针
应用场景:内存管理、DOM 节点操作、LRU 缓存
代码示例

class ListNode {constructor(val, next) {this.val = (val === undefined ? 0 : val);this.next = (next === undefined ? null : next);}
}// 链表反转
function reverseList(head) {let prev = null;let current = head;while (current) {const next = current.next;current.next = prev;prev = current;current = next;}return prev;
}

使用建议

  1. 插入 / 删除操作优先使用链表
  2. 实现双向链表时维护好前驱指针
  3. 使用虚拟头节点简化边界条件处理

注意事项

  • 避免循环引用导致内存泄漏
  • 注意空指针检查
  • 遍历链表时设置终止条件
  • 内存分配比数组更碎片化

三、栈(Stack)

定义:遵循后进先出(LIFO)原则的线性结构
应用场景:路由管理、撤销重做、函数调用栈
代码示例

class Stack {constructor() {this.items = [];}push(element) {this.items.push(element);}pop() {return this.items.pop();}peek() {return this.items[this.items.length - 1];}
}// 浏览器路由栈模拟
const routerStack = new Stack();
routerStack.push('/home');
routerStack.push('/about');
routerStack.pop(); // 返回 '/about',当前栈顶 '/home'

使用建议

  1. 用数组实现简单栈时,直接使用 push/pop
  2. 需要高性能时考虑使用 Uint8Array 实现
  3. 限制栈的最大深度防止溢出

注意事项

  • 处理栈溢出(Stack Overflow)
  • 避免在栈中存储过大对象
  • 递归深度受限于栈大小

四、队列(Queue)

定义:遵循先进先出(FIFO)原则的线性结构
应用场景:任务调度、事件队列、消息缓冲
代码示例

class Queue {constructor() {this.items = [];}enqueue(element) {this.items.push(element);}dequeue() {return this.items.shift();}front() {return this.items[0];}
}// 任务队列处理
const taskQueue = new Queue();
taskQueue.enqueue(() => console.log('Task 1'));
taskQueue.enqueue(() => console.log('Task 2'));
taskQueue.dequeue()(); // 执行 Task 1

使用建议

  1. 优先使用 enqueue + pop 替代 shift
  2. 使用双端队列(Deque)实现更灵活操作
  3. 限制队列长度防止内存耗尽

注意事项

  • 避免饥饿问题(高优先级任务阻塞队列)
  • 处理并发访问时需加锁
  • 内存泄漏风险(未及时释放旧任务)

五、哈希表(Hash Table)

定义:通过哈希函数将键映射到存储位置的结构
应用场景:状态管理、缓存、快速查找
代码示例

class HashTable {constructor(size = 1024) {this.table = new Array(size);this.size = size;}hash(key) {let hash = 0;for (let i = 0; i < key.length; i++) {hash += key.charCodeAt(i);}return hash % this.size;}set(key, value) {const index = this.hash(key);this.table[index] = value;}get(key) {const index = this.hash(key);return this.table[index];}
}// 简单状态管理
const state = new HashTable();
state.set('user', { name: 'John', age: 30 });
console.log(state.get('user'));

使用建议

  1. 选择合适的哈希函数(如 BKDRHash)
  2. 负载因子控制在 0.75 以下
  3. 实现冲突解决(开放寻址法 / 链地址法)

注意事项

  • 哈希冲突的处理
  • 键的可哈希性(对象需重写 toString)
  • 动态扩容的性能消耗

六、树(Tree)

定义:n 个节点构成的有限集合,具有层次关系
应用场景:DOM 树、路由配置、算法优化
代码示例

class TreeNode {constructor(val) {this.val = val;this.left = null;this.right = null;}
}// 二叉树前序遍历
function preorderTraversal(root) {const result = [];function traverse(node) {if (!node) return;result.push(node.val);traverse(node.left);traverse(node.right);}traverse(root);return result;
}// 构建DOM树
const div = document.createElement('div');
const span = document.createElement('span');
div.appendChild(span);

使用建议

  1. 使用递归实现树遍历需注意栈溢出
  2. 优先使用迭代法(如 Morris 遍历)优化空间复杂度
  3. 树的深度控制在合理范围

注意事项

  • 树的平衡问题(AVL 树 / RBTree)
  • 内存泄漏(未释放子节点引用)
  • 遍历顺序的选择(前序 / 中序 / 后序)

七、图(Graph)

定义:由节点和边构成的非线性结构
应用场景:社交网络、路径规划、依赖分析
代码示例

class Graph {constructor() {this.adjList = new Map();}addVertex(vertex) {if (!this.adjList.has(vertex)) {this.adjList.set(vertex, new Set());}}addEdge(v1, v2) {if (this.adjList.has(v1) && this.adjList.has(v2)) {this.adjList.get(v1).add(v2);this.adjList.get(v2).add(v1);}}bfs(start) {const visited = new Set();const queue = [start];visited.add(start);while (queue.length) {const node = queue.shift();console.log(node);this.adjList.get(node).forEach(neighbor => {if (!visited.has(neighbor)) {visited.add(neighbor);queue.push(neighbor);}});}}
}// 页面依赖关系图
const graph = new Graph();
graph.addVertex('A');
graph.addVertex('B');
graph.addEdge('A', 'B');
graph.bfs('A'); // 输出 A -> B

使用建议

  1. 选择邻接表存储稀疏图
  2. 使用邻接矩阵存储稠密图
  3. 路径查找使用 Dijkstra/A * 算法

注意事项

  • 图的遍历需要标记访问状态
  • 处理环的问题(强连通分量)
  • 内存消耗较大,需注意优化

总结建议

  1. 空间与时间权衡:根据数据量和操作类型选择结构
  2. 性能优化:避免在高频操作中使用低效率方法
  3. 内存管理:及时释放不再使用的结构引用
  4. 算法适配:不同场景选择对应算法(如树用 DFS,图用 BFS)
  5. 边界处理:空值检查、越界处理等防御性编程

建议在实际开发中建立数据结构选择决策表,根据具体场景评估时间复杂度、空间复杂度和操作频率,同时结合浏览器 / Node.js 环境特性进行优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/74098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka 的高可用性

Kafka 的高可用性主要通过副本机制、ISR&#xff08;In-Sync Replicas&#xff09;列表和控制器 Broker 来实现。这些机制共同确保了 Kafka 集群在部分节点故障时仍然可以正常运行&#xff0c;数据不会丢失&#xff0c;并且服务不会中断。 1. 副本机制 Kafka 的副本机制是其高…

力扣HOT100之矩阵:54. 螺旋矩阵

这道题之前在代码随想录里刷过类似的&#xff0c;还有印象&#xff0c;我就按照当初代码随想录的思路做了一下&#xff0c;结果怎么都做不对&#xff0c;因为按照代码随想录的边界条件设置&#xff0c;当行数和列数都为奇数时&#xff0c;最后一个元素无法被添加到数组中&#…

快速构建个人本地知识库管理系统与实现RAG问答

文章目录 摘要一、RAG 和知识库简介1、RAG2、知识库 二、 工作流程三、系统架构设计文件结构知识库构建模块RAG 模块用户交互模块 四、技术实现细节五、系统使用案例结论未来改进方向致谢 摘要 在当今信息爆炸的时代&#xff0c;快速准确地获取知识变得尤为重要。本地 RAG&…

使用DeepSeek API进行情感分析:超简单

文章目录 1. 引言1.1 情感分析概述1.2 为什么选择DeepSeek API1.3 本文目标 2. 技术方案对比2.1 传统情感分析方法2.2 基于LLM的方法DeepSeek API优势 3. DeepSeek 情感分析实战3.1 Few-shot Learning方法3.2 完整的DeepSeek API调用示例3.3 案例演示 4. DeepSeek开发情感分析工…

设置网站主题色color-scheme

color-scheme color-scheme CSS 属性允许元素指示它可以舒适地呈现哪些颜色方案。 操作系统颜色方案的常见选择为“亮色”和“暗色”&#xff0c;或“日间模式”和“夜间模式”。当用户选择其中一种颜色方案时&#xff0c;操作系统会对用户界面进行调整&#xff0c;包括表单控件…

Muduo网络库实现 [三] - Socket模块

目录 设计思路 类的设计 模块的实现 基础模块 特殊模块 集成模块 主函数 主函数实现 主函数测试 疑惑点 设计思路 Socket模块主要是对套接字的基础操作进行封装&#xff0c;简化我们对套接字的操作&#xff0c;不需要调用C的原生接口&#xff0c;而是以面向对象的…

优选算法的巧思之径:模拟专题

专栏&#xff1a;算法的魔法世界 个人主页&#xff1a;手握风云 目录 一、模拟 二、例题讲解 2.1. 替换所有的问号 2.2. 提莫攻击 2.3. Z字形变换 2.4. 外观数列 2.5. 数青蛙 一、模拟 模拟算法说简单点就是照葫芦画瓢&#xff0c;现在草稿纸上模拟一遍算法过程&#xf…

贪心算法(13)(java)合并区间

题目&#xff1a; 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff…

A股复权计算_权息数据整理

目录 前置&#xff1a; 步骤&#xff1a; 1 以通达信为参照 2 从优矿获取所需数据 2.1 股票配股信息 2.2 股票分红信息 2.3 股票拆股信息 3 合并数据&#xff0c;制成权息数据表 权息数据截止20250329.7z 视频 前置&#xff1a; 1 本系列将以 “A股复权计算_” 开头…

学习笔记—数据结构—二叉树(链式)

目录 二叉树&#xff08;链式&#xff09; 概念 结构 初始化 遍历 前序遍历 中序遍历 后序遍历 层序遍历 结点个数 叶子结点个数 第k层结点个数 深度/高度 查找值为x的结点 销毁 判断是否为完整二叉树 总结 头文件Tree.h Tree.c 测试文件test.c 补充文件Qu…

Open GL ES ->GLSurfaceView在正交投影下的图片旋转、缩放、位移

XML文件 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:o…

Day78 | 灵神 | 反转链表 两两交换链表中的节点

Day78 | 灵神 | 反转链表 两两交换链表中的节点 24.两两交换链表中的节点 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 这道题就是下面这道题的k2的情况 25. K 个一组翻转链表 - 力扣&#xff08;LeetCode&#xff09; 基本思路和…

滤波---卡尔曼滤波

卡尔曼滤波概览 一、定义 卡尔曼滤波是一种基于线性系统和高斯噪声假设的递归最优状态估计算法。其核心目标是通过融合系统模型预测值与传感器测量值&#xff0c;在噪声环境中实时估计系统的动态状态&#xff08;如位置、速度、加速度等&#xff09;。 数学基础&#xff1a; …

23种设计模式-结构型模式-桥接器

文章目录 简介问题解决方案示例总结 简介 桥接器是一种结构型设计模式&#xff0c;可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构&#xff0c;从而能在开发时分别使用。 问题 假如你有一个几何形状Shape类&#xff0c;它有两个子类&#xff1a;圆形C…

手工排查后门木马的常用姿势

声明&#xff01;本文章所有的工具分享仅仅只是供大家学习交流为主&#xff0c;切勿用于非法用途&#xff0c;如有任何触犯法律的行为&#xff0c;均与本人及团队无关&#xff01;&#xff01;&#xff01; 1. 检查异常文件 &#xff08;1&#xff09;查找最近修改的文件 # 查…

工业机器人核心算法体系解析:从感知到决策的技术演进

工业机器人作为智能制造的核心装备,其技术竞争力的本质是算法体系的优化与创新。从静态轨迹执行到动态环境适应,从单一任务控制到复杂场景决策,工业机器人的算法体系涵盖环境感知、运动控制、路径规划、行为决策四大核心模块。本文将深入解析各模块的关键算法及其技术演进,…

当 EcuBus-Pro + UTA0401 遇上 NSUC1500

文章目录 1.前言2.EcuBus-Pro简介2.1 官方地址2.2 概览 3.纳芯微NSUC1500简介3.1 NSUC1500概述3.2 产品特性 4.测试环境5.基础功能5.1 数据发送5.2 数据监控 6.自动化功能6.1 脚本创建6.2 脚本编辑6.3 脚本编辑与测试 7.音乐律动7.1 导入例程7.2 效果展示 ECB工程 1.前言 最近…

说说Redis的内存淘汰策略?

大家好&#xff0c;我是锋哥。今天分享关于【说说Redis的内存淘汰策略?】面试题。希望对大家有帮助&#xff1b; 说说Redis的内存淘汰策略? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis的内存淘汰策略用于管理当内存达到最大限制时&#xff0c;如何处理过…

Python实现音频数字水印方法

数字水印技术可以将隐藏信息嵌入到音频文件中而不明显影响音频质量。下面我将介绍几种在Python中实现音频数字水印的方法。 方法一&#xff1a;LSB (最低有效位) 水印 import numpy as np from scipy.io import wavfile def embed_watermark_lsb(audio_path, watermark, ou…

Altium Designer 24 PCB 走线倒圆弧方法

Altium Designer 24 PCB 走线倒圆弧方法 问题描述解决方法设置倒圆弧参数选择需要优化的走线进行走线优化 优化效果展示 在 PCB 设计中&#xff0c;走线转角过于尖锐不仅影响美观&#xff0c;还可能引起信号完整性问题。本文介绍如何在 Altium Designer 24 中通过倒圆弧优化走线…