chapter-6 链表
数组的缺点
- 很多语言里,数组的长度固定。填满后,加入新元素很困难。
- 添加、删除元素也很麻烦,因为需要将数组中其他元素向前或向后平移,以反映刚刚进行了添加或删除操作。
- JavaScript数组不存在上述问题,split方法不需要再访问数组中其他元素了,主要问题是:它们被实现成了对象,与其他语言相比,效率很低。
- 如果数组使用中很慢,可以考虑用链表代替它,除了对数据的随机访问,链表几乎可以用在任何可以使用一维数组的情况。需要随机访问,数组是更好的选择。
定义链表
- 一组节点组成的集合。
- 每个节点使用一个对象的引用指向它的后继。指向另一个节点的引用叫做链。
- 数组靠位置进行引用,链表靠相互之间的关系进行引用。
- 遍历链表是跟着链接,从首元素走到尾元素(不包含头节点,作为链表的接入点),尾元素指向一个null节点。
- 头节点是一个特殊固定节点。
- 插入一个节点的效率很高,修改它前面的节点(前驱),使其指向新加入的节点,新加入的节点则指向原来前驱指向的节点。
- 删除一个节点,将待删除元素的前驱节点指向待删除元素的后继节点,同时将待删除元素指向null
设计一个基于对象的链表
- 包含两个类:Node类用来表示节点,LinkedList类提供插入、删除、显示列表元素、及一些辅助方法。
|
|
双向链表
- 从链表的头节点遍历到尾节点很简单,但是反过来,从后向前遍历则没那么简单。给Node增加一个属性,存储指向前驱节点的链接。
- 插入时,需要更多的工作,指出节点正确的前驱和后继。
- 删除时,效率提高了,不需要再查找待删除节点的前驱节点了。
|
|
计算了一下时间:
- 插入10000个Node的时间
- 普通链表和双向链表差不多,普通链表240ms,双向链表250ms
- 依次删除这全部10000个节点
- 普通链表在150ms左右
- 双向链表时间则较长,需要230ms左右
- 随机删除一个元素(Math.random())
- 普通链表平均:0.283ms
- 双向链表平均:0.196ms
所以书上写的双向链表更高效应该是指随机删除任意一个元素的平均时间
循环链表
- 节点类型和单向链表类似,区别是,创建循环链表时,让其头节点的next属性指向它本身。
- 希望可以从后向前遍历链表,但是又不想付出额外代价来创建一个双向链表,就需要使用循环链表。
- 从循环链表的尾节点向后移动,就等于从后向前遍历链表
|
|
一般正常情况所说的链表都是双向链表,比较快