js链表的实现
linkedList.js
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
this.tail = this.head;
this.length = 0;
}
/**
* 遍历链表
* @param callback
*/
iterator(callback) {
let current = this.head;
let prevNode = null;
let nextNode = current.next;
while (current) {
callback(prevNode,current,nextNode);
prevNode = current;
current = current.next || null;
nextNode = current?.next || null;
}
}
/**
* 获取指定元素的索引
* @param {*} node
* @param {*} keyField
* @returns
*/
indexOf(node,keyField) {
let current = this.head;
let index = 1; // 记录元素的位置
while (current) {
// 循环遍历链表
if(keyField) {
if(current.data[keyField] === node.data[keyField]) {
// 如果当前节点的值等于元素的值
return index; // 返回位置
} else {
// 如果不等于,继续循环
current = current.next;
index++;
}
} else {
if(current.data === node.data) {
// 如果当前节点的值等于元素的值
return index; // 返回位置
} else {
// 如果不等于,继续循环
current = current.next;
index++;
}
}
}
return -1; // 循环结束了,说明没找到
}
/**
* 修改节点数据
* @param {*} data
*/
set(index,data) {
const { currNode } = this.getContext(index);
currNode.data = data;
}
/**
* 顺序添加节点
* @param {*} data
*/
append(data) {
const newNode = new Node(data);
if(!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
this.length++;
return newNode;
}
/**
* 将值添加到链表的开头
* @param {*} data
*/
prepend(data) {
const newNode = new Node(data);
newNode.next = this.head;
this.head = newNode;
this.length++;
}
/**
* 获取当前索引节点的上下文
* @param {*} index
* @returns
*/
getContext(index) {
let count = 1;
let prevNode = null;
let currNode = this.head;
let nextNode = currNode ? currNode.next : null;
while (count < index) {
prevNode = currNode;
currNode = currNode ? currNode.next : null;
nextNode = nextNode ? nextNode.next : null;
count++;
}
return {
prevNode,
currNode,
nextNode,
};
}
/**
* 在特定索引之后添加值
* @param {*} data
* @param {*} index
*/
insert(data,index) {
if(index < 1 || index > this.length) {
console.error("插入失败,索引超出");
return;
}
const newNode = new Node(data);
const { currNode,nextNode } = this.getContext(index);
currNode.next = newNode;
newNode.next = nextNode;
this.length++;
}
/**
* 删除特定索引处的元素
* @param {*} index
*/
remove(index) {
if(index < 1 || index > this.length) {
console.error("删除失败,索引超出");
return;
}
const { prevNode,currNode } = this.getContext(index);
if(prevNode) {
prevNode.next = currNode.next;
} else {
this.head = currNode.next;
}
this.length--;
}
/**
* 调换元素位置
*/
swapNodes(node1,node2,keyField) {
const index1 = this.indexOf(node1,keyField);
const index2 = this.indexOf(node2,keyField);
const { prevNode: prevNode1,nextNode: nextNode1 } = this.getContext(index1);
const { prevNode: prevNode2,nextNode: nextNode2 } = this.getContext(index2);
prevNode1.next = node2;
node2.next = nextNode1;
prevNode2.next = node1;
node1.next = nextNode2;
}
/**
* 翻转链表
*/
reverse() {
let previousNode = null;
let currentNode = this.head;
while (currentNode !== null) {
let nextNode = currentNode.next;
currentNode.next = previousNode;
previousNode = currentNode;
currentNode = nextNode;
}
this.head = previousNode;
}
}
export { LinkedList };