链表的特点
- 中链表由节点组成,一个节点包含一份储存的数据和一个指针,指针指向下一个节点或 null
- 链表在内存中不是连续的,数组是连续的
- 增加和删除数据的效率高,数组增加和删除数据的效率低
- 但是查找数据效率低,只能通过循环遍历,数组查找效率很高因为是连续的可以直接通过索引查找
- 链表方便拓展,定义时不需要需要指定大小,数组不利于拓展要指定大小
链表的实现
class LinkedListNode {
constructor(data) {
this.data = data;
this.next = null;
}
}
const head = Symbol('head');
class LinkedList {
constructor() {
this[head] = null;
}
// 在尾部增加节点
addLast(data) {
const newNode = new LinkedListNode(data);
if (this[head] === null) {
this[head] = newNode;
} else {
let current = this[head];
while (current.next !== null) {
current = current.next;
}
current.next = newNode;
}
}
// 在某节点前增加数据
insertBefore(data, index) {
const newNode = new LinkedListNode(data);
if (this[head] === null) {
throw RangeError(`Index ${index} does not exist in the list.`);
}
if (index === 0) {
newNode.next = this[head];
this[head] = newNode;
} else {
let current = this[head];
let previous = null;
let i = 0;
while (i < index && current.next !== null) {
previous = current;
current = current.next;
i++;
}
if (i < index) {
throw RangeError(`Index ${index} does not exist in the list.`);
}
previous.next = newNode;
newNode.next = current;
}
}
// 在某节点后增加数据
insertAfter(data, index) {
const newNode = new LinkedListNode(data);
if (this[head] === null) {
throw RangeError(`Index ${index} does not exist in the list.`);
}
let i = 0;
let current = this[head];
while (i < index && current.next !== null) {
current = current.next;
i++;
}
if (i < index) {
throw RangeError(`Index ${index} does not exist in the list.`);
}
newNode.next = current.next;
current.next = newNode;
}
// 查找数据
get(index) {
if (index > -1) {
let current = this[head];
while (current !== null && index > 0) {
current = current.next;
index -= 1;
}
return current !== null ? current.data : undefined;
} else {
return undefined;
}
}
// 删除某数据
remove(index) {
if (this[head] === null || index < 0) {
throw new RangeError(`Index ${index} does not exist in the list.`);
}
let current = this[head];
let previous = null;
let i = 0;
if (index === 0) {
this[head] = current.next;
current.next = null;
return current.data;
}
while (current !== null && i < index) {
previous = current;
current = current.next;
i++;
}
if (current !== null) {
previous.next = current.next;
current.next = null;
return current.data;
}
throw new RangeError(`Index ${index} does not exist in the list.`);
}
}
常见题目:反转链表
反转整个链表
function reverse(a) {
let pre = null;
let cur = a;
let nxt = a;
while (cur != null) {
nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
反转部分链表
function reverseGroup(a, b) {
let pre = null;
let cur = a;
let nxt = a;
while (cur != b) {
nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return pre;
}