JavaScript 中可通过对象和引用机制实现链表与树结构,其核心是“节点+引用”的建模思想,适用于处理复杂逻辑、层级关系或特定算法场景。
一、链表的实现与应用1. 基本结构链表由节点(包含数据和指向下一个节点的指针)组成,插入和删除操作效率高于数组,适合频繁修改的场景。
- 节点类:class ListNode { constructor(val) { this.val = val; this.next = null; }}
- 链表类:class LinkedList { constructor() { this.head = null; } append(val) { const node = new ListNode(val); if (!this.head) { this.head = node; } else { let current = this.head; while (current.next) { current = current.next; } current.next = node; } }}
2. 常见应用场景
- 队列实现:通过链表尾部插入、头部删除实现先进先出(FIFO)。
- 大数相加:如 LeetCode 第2题,用链表存储数字的每一位,模拟手工加法过程。
- 浏览器历史记录管理:链表结构可高效处理前进/后退操作。
- LRU 缓存淘汰策略:双向链表结合哈希表,实现 O(1) 时间复杂度的插入、删除和访问。
二、二叉树的实现与遍历1. 基本结构二叉树每个节点最多有两个子节点(左、右),常用于搜索、表达式解析和层级数据展示。
- 节点类:class TreeNode { constructor(val) { this.val = val; this.left = null; this.right = null; }}
2. 遍历方式
- 前序遍历:根 → 左子树 → 右子树(适合复制树)。function preorder(root) { if (!root) return; console.log(root.val); // 访问根 preorder(root.left); // 遍历左子树 preorder(root.right); // 遍历右子树}
- 中序遍历:左子树 → 根 → 右子树(二叉搜索树中可得到有序序列)。function inorder(root) { if (!root) return; inorder(root.left); // 遍历左子树 console.log(root.val); // 访问根 inorder(root.right); // 遍历右子树}
- 后序遍历:左子树 → 右子树 → 根(适合释放节点或计算目录大小)。function postorder(root) { if (!root) return; postorder(root.left); // 遍历左子树 postorder(root.right); // 遍历右子树 console.log(root.val); // 访问根}
- 迭代实现:需配合栈结构模拟递归过程。
3. 实际应用场景
- DOM 树:浏览器中的 DOM 结构本质是一棵树,可通过递归遍历操作节点。
- 状态管理:如 Redux 中,应用状态常以树形组织,便于更新和追踪。
- 层级数据展示:菜单、组织架构等具有层级关系的数据可用树结构表示。
三、关键注意事项四、总结- 链表:通过节点和指针实现,适合动态增删场景,如队列、LRU 缓存。
- 树:通过节点和左右子节点引用实现,支持高效搜索和层级数据处理,如 DOM 操作、状态管理。
- 核心思想:掌握“节点+引用”的建模方式,结合递归或迭代处理复杂逻辑。