不论是何种语言的开发,数据结构 和 算法 都是最基础的知识,这也是科班和培训班的主要差别之一,这篇文件将介绍一下常见的数据结构。
一、线性表
这是一种线性结构,直观的看,是一些元素排成一行,在线性表中,又可以分为 数组、链表、栈、队列 这四类。
1. 数组
数组在计算机内存里往往是连续的一块,数组中的元素由下标唯一确定,因此在数组中获取元素的复杂度是
在其他语言比如 C 里,数组还有“越界”的报错,表示访问了数组下标范围之外的地方,当然在 JS 中没有越界报错,会得到 undefined。
2. 链表
链表中的每个元素都保留了下一个元素的引用,像链条一样串联起来,所以在链表中获取一个元素,需要从头开始遍历,复杂度是
当链表的最后一个元素指向前面的元素时,将形成 环;当元素还包含指向前一个节点指针时,就形成了 双向链表。
3. 栈
栈是一种只能在末尾增删元素的数据结构,先进后出,JS 数组的 push/pop 方法,其实就是栈操作。栈一般用于有匹配关系的场景,比如判断括号是否匹配;在搜索中,栈对应了 DFS,即深度优先遍历。
4. 队列
队列则是只能在队头删除元素、队尾增加元素,先进先出,JS 数组的 shift/push 方法,就是队列操作。队列一般用于生产/消费场景,生产者往队列里丢任务,消费者按次序处理;在搜索中,队列对应了 BFS,即广度优先遍历。
二、树
线性表的元素 只有一个前驱结点和一个后继节点,当元素 只有一个前驱节点但有多个后继节点 时,就形成了树。树在前端最典型的应用场景是目录树,另外,二叉树 和 二叉堆 也是常用的数据结构。
二叉树表示每个节点最多有两个子节点,二叉堆在二叉树的基础上,要求父节点都必须不小于子节点(即 最大堆,相应的如果是不大于,则是 最小堆)。借助堆,可以实现一个高效的 优先级队列。
树的主要操作是遍历,需要掌握 前序/中序/后序/层次 等遍历方式。
三、图
如果元素有 多个前驱节点和多个后继节点,则形成了图。生活中的地图就是最典型的图,图的主要操作有查找、最短路径等,常常用到 DFS 和 BFS。
四、散列表
散列表是一种将元素通过 hash 函数直接映射到内存的数据结构,编程语言里的 Map(或者字典)就是散列表,也叫 Hash 表,它的操作基本都是在 O(1) 时间里完成,非常高效。开发中我们一般不需要自己设计散列表,但是仍有必要了解这个数据结构。
本文介绍了线性表、树、图、散列表四种常见的数据结构,这对我们认识数据、设计数据模型是很重要的,也是从“调用工程师”迈向“开发工程师”的第一步,下篇文章将介绍常用算法。
感谢阅读。