链表是一种有序的数据结构。它是一种更好的数据存储方式优化数组的存储功能。
- 链表中的每个部分称为节点。
- 链表可以从首、尾、中间的任意位置进行数据存储。
- 链表的元素在内存中不必是连续的空间。
优点:添加和删除时不会导致元素的位移。缺点:不可以快速根据索引定位元素。
数组存储有序数列。在内存中占有一段连续的空间。添加、移除会导致后续元素的位移,性能开销大。eg:array.push() >>> array.unshift()
对比:获取、修改元素时,数组效率高。添加、删除元素时,链表效率高。
链表的实现
需要实现的主要功能:
- 节点类: value、next
- 链表类
- addAtTail()尾部添加节点
- addAtHead()头部添加节点
- addAtIndex ()指定位置添加节点
- get()获取节点
- removeAtIndex()删除指定节点
代码实现:
//节点类
class LinkedNode {
constructor(value) {
this.value = value;
//用于存储下一个节点的引用
this.next = null;
}
}
//链表类
class LinkedList {
constructor() {
this.count = 0;
this.head = null;
}
// 添加节点(首)
addAtHead(value) {
//创建新节点
const node = new LinkedNode(value);
//检测链表是否存在数据
if (this.count === 0) {
this.head = node;
} else {
// 将 node 添加到 head 的前面
node.next = this.head;
this.head = node
}
this.count++
}
// 添加节点(尾)
addAtTail(value) {
//创建新节点
const node = new LinkedNode(value);
//检测链表是否存在数据
if (this.count === 0) {
this.head = node;
} else {
//找到链表的尾部节点,将最后一个节点的 next 设置为 node。
let current = this.head;
if (current.next != null) {
current = current.next;
}
current.next = node
}
this.count++
}
// 根据索引获取节点
get(index) {
if (index >= this.count || index < 0 || this.count === 0) {
return
}
//迭代链表,找到对应节点
let current = this.head
for (let i = 0; i < index; i++) {
current = current.next
}
return current
}
// 根据索引添加节点
addAtIndex(value, index) {
if (this.count === 0 || index >= this.count) {
return
}
if (index <= 0) {
return this.addAtHead(value)
}
//下面为正常区间的处理
const present = this.get(index - 1) const next = present.next const node = new LinkedNode(value) present.next = node node.next = next this.count++
return LinkedList
}
//按照索引删除指定元素,头部删除设置为头后面的元素,尾补删尾部前面的元素的next设置为null
removeAtIndex(index) {
if (this.count === 0 || index < 0 || index >= this.count) {
return
}
if (index === 0) {
this.head = this.head.next
} else {
const prev = this.get(index - 1) prev.next = prev.next.next
}
this.count--
}
}
const l = new LinkedList() l.addAtTail("a") l.addAtTail("b") l.addAtTail("c")
双向链表
双向链表指的是在普通链表的基础上,增加一个用于记录上一个节点的属性prev,可进行双向访问。
循环链表
循环链表又称为环形链表,指的是链表最后一个节点的 next 指向第一个节点,形成首尾相连的循环结构,称为循环列表。在实际使用中,环的结束点可以为链表的任意节点。