JS 数据结构

一、认识数据结构

什么是数据结构?下面是维基百科的解释

数据结构是计算机存储、组织数据的方式

数据结构意味着接口或封装:一个数据结构可被视为两个函数之间的接口,或者是由数据类型联合组成的存储内容的访问方法封装

我们每天的编码中都会用到数据结构,因为数组是最简单的内存数据结构,下面是常见的数据结构:

  • 数组(Array)
  • 栈(Stack)
  • 堆(Heap)
  • 队列(Queue)
  • 链表(Linked List)
  • 树(Tree)
  • 图(Graph)
  • 散列表(Hash)

其中,队列是一种类似数组的数据结构,它们之间的区别仅仅体现在数据项的插入和移除的方式上。链表则是另一种节点与节点之间维持引用关系的数据结构。散列表(也称哈希表)依赖散列函数来保存和定位数据。

就复杂性而言,栈和队列是最简单的两种,并且二者都可以通过链表来进行构造。树和图则是最复杂的,因为它们继承了链表的概念。散列表需要利用这些数据结构来可靠地执行。就执行效率而言,链表在对数据的记录和排序上表现最好,同时散列表也更加擅长查找和提取数据。

二、栈、堆、队列

详见

三、链表(Linked List)

如同数组一样,链表也是按照顺序存储数据元素,但却不是通过维护索引实现,链表是通过指向其他节点的指针实现。第一个节点称之为头节点,最后一个节点被称为尾节点。在单向链表中,每个节点都只有一个指针,该指针指向下一个节点。我们从头结点开始向后遍历链表中剩余的节点。在双向链表中,还有一个指向前一个节点的指针,因此可以实现从尾部向头部「反向」遍历链表。

由于只需要改变节点的指针,所以链表插入和删除某个节点操作所消耗的时间是固定的。在数组中执行同样的操作需要消耗的时间却是线性增长的,因为紧随其后的节点都需要被移动。另外,只要还有空间,链表就可以增长。因此,即使是自动调整大小的「动态」数组,操作代价也可能变得出乎意料的高。为了查找或者编辑链表中的某个元素,可能会遍历整个链表,遍历的时间复杂度是线性的。但如果使用数组索引,却只需要花费一丁点的时间。

四、树(Tree)

树(Tree)类似于链表,但不同的是树在不同的层级下引用多个子节点。换句话说,每个节点最多只能有一个父节点。文档对象模型(DOM)就是这样的结构,有一个根节点 html, html 中的分支都包含在 head 和 body 节点中,然后进一步细分为所有我们熟悉的 HTML 标签。在 JS 内部,原型继承和与 React 组件的组合也会产生树结构。当然,React 中作为代表内存中 DOM 结构的虚拟 DOM,同样也是一个树结构。

二叉树是一种比较特殊的树,因为二叉树中的每个节点最多只能有两个子节点。左子节点的值必须小于或等于其父节点的值,同时右子节点的值必须大于其父节点的值。以这种方式组织和平衡树结构,由于每次迭代中我们可以忽略二分之一的分支,所以就可以在对数时间内查找任意值。插入和删除操作同样也在对数时间内完成。除此之外,可以轻松地最左叶节点中和最右叶节点中,分别找到最小值和最大值。

对树的遍历可以以垂直或水平过程进行。深度优先遍历(DFT)是在垂直方向上,其递归算法相较于迭代算法来说更加优雅。可以通过前序、中序、后序来遍历节点。如果需要先访问根节点,然后再检查子节点,应该选择前序遍历。如果需要先访问子节点,然后再检查根节点,则应选择后序遍历。顾名思义,中序遍历就是按照左、根、右的顺序遍历节点。这些性质使得二叉查找树非常适合排序。

广度优先遍历(BFT)是在水平方向上,其迭代算法相较于递归算法来说更加优雅。广度优先遍历需要使用队列来跟最每次迭代的所有子节点。但是,此类队列所需的内存可能并不小。如果树的形状更宽,则广度优先遍历是更好的选择。同样,广度优先遍历在任何两个节点之间采用的路径是最短的路径。

五、图(Graph)

如果一棵树可以拥有多个父节点,那么它就变成了一张图(Graph)。在图中连接每个节点的边,可以是有方向的,也可以是无方向的,可以是有权重的,也可以是无权重的。既有方向也有权重的边类似于向量。

社交网络和互联网本身也是图。自然界中最复杂的图是我们人类的大脑。现在,我们试图将神经网络复制到机器中,期望使机器具有「超级智能」。

六、散列表(Hash Table)

列表是一种包含键值(Key-Value)对的,类似字典的数据结构。在内存中的每对键值都通过散列函数(Hash Function)来确定其位置,散列函数接受键(Key)作为参数,并返回该键值对应当插入或读取的地址。如果两个或者多个键返回的地址是相同的,则会发生冲突(Collision)。为了健壮起见,getter 和 setter 应该预见到这些事件,以确保可以恢复所有的数据,并且不会覆盖任何数据。通常,可以使用链表来实现最简单的解决方案,或者搞一个超大的表也是可行的。

 

参考:https://juejin.im/post/5de754faf265da33b12e8615

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章