数据结构简介
数据结构是相互之间存在一种或者多种特定关系的数据元素的集合数据结构分为逻辑结构和物理结构;数据对象中数据元素之间的关系称为逻辑结构, 在数据结构中, 存在下面四种逻辑结构:
- 集合结构集合结构中的元素除了同属于同一集合之外。 没有其他的任何关系, 如同所示:
- 线性结构: 线性结构中的元素是一对一的关系:
- 树形结构:树形结构中的元素关系是一对多的层次关系, 比如: 二叉树
- 图形结构: 图形结构中的元素之间的关系是一对多的关系

数据结构之线性表
线性表是零个或者多个数据元素的有限序列线性表是一种序列, 这表明线性表中数据的关系之间都是一对一的关系,如果元素存在多个, 那么第一个元素没有前元素, 最后一个元素没有后元素, 其他元素有且只有一个前元素和后元素,
线性表的顺序存储结构
顺序存储结构是物理结构和逻辑结构一致的一种结构, 比如, 我们使用一个一维数组来存储数据,实现顺序存储结构;1 | let list = [1, 2, 3, 4]; |
list[i - 1]
来获取数据。删除和插入元素
当我们需要删除或者插入元素的时候, 对于顺序存储结构需要移动比较多的元素, 当我们需要删除一个元素, 需要将该数据项后面的数据都需要向前提前一位:1 | // 从线性表中删除某个数据 |
优缺点
对于线性表的顺序存储结构, 其优点是:- 可以快速的存取表中任意位置的元素
- 无须为表中的逻辑关系增加额外的存储空间
线性表的链式存储结构
顺序存储结构对于插入和删除元素需要移动大量元素的原因是数据之间的逻辑关系和存储关系一致且相互之间按照次序排列,需要移动大量的元素来保持相互之间的存储关系和逻辑关系的一致。这种问题可以通过使用链式存储结构来解决,链式存储结果的特点是逻辑关系和存储关系分离, 当逻辑关系改变时, 不会引起存储关系的变化线性表的链式结构由一个个的节点(Node)构成, 每个节点中包含有一个数据域和一个或者多个指针域, 顾名思义, 数据域用于存储当前节点的数据, 指针域用来存储下一个节点的位置信息, 根据节点中指针域的数量不同, 将链表分为单链表和双链表;单链表
单链表示意图如下:

- 链表中的最后一个节点的指针为空, 我们常常将其置为
null
- 为了更方便的对于链表进行操作, 我们在第一个节点之前设置一个头节点,这个节点的指针指向第一个节点, 节点中的数据可以包含有链表的长度等信息。
- 头指针不为空,是链表的必要元素


单链表的读取
链表中数据的关系是通过指针来表示的,想要读取单链表的数据,我们需要通过指针来操作, 比如读取程序如下:1 | // 创建一个新的链表 |
单链表的插入和删除
代码如下:1 | // 在第 i 个数据后插入元素, 元素值为 value |


p
节点之后插入节点 s
, 我们要做的是将 p 节点的指针 next
指向要插入的节点, 同时将要插入的节点的指针指向插入前的下一个节点。注意: 这里的顺序是:1 | s.next --> p.next; |




1 | // 删除第 i 个节点的元素 |
单链表的整表删除
1 | this.deleteAll = function () { |
循环链表
在单链表中终端节点的指针端由空指针指向头节点,就使得整个单链表形成一个环,这种头尾相接的链表称为循环链表循环链表如下图所示:


双向链表
双向链表和单链表的区别在于: 实现双向链表的节点中存在两个指针域,在单链表的基础上,创建另外一个指针指向上一个节点,如下图所示:
