JavaScript链表实现
链表中的常见操作
append(element)向链表尾部添加一个新的项。insert(position, element)向链表的特定位置插入一个新的项。get(position)获取对应位置的元素。indexOf(element)返回元素在链表中的索引。如果链表中没有该元素就返回-1。update(position, element)修改某个位置的元素。removeAt(position)从链表的特定位置移除一项。remove(element)从链表中移除一项。isEmpty()如果链表中不包含任何元素,返回 trun,如果链表长度大于 0 则返回 false。size()返回链表包含的元素个数,与数组的 length 属性类似。toString()由于链表项使用了 Node 类,就需要重写继承自 JavaScript 对象默认的 toString 方法,让其只输出元素的值。
/**
-
单向链表 */ class LinkedList { // 初始长度为0 length = 0; // 初始head为null, head指向链表的第一个节点 head = null;
// 内部类(链表里的节点Node) Node = class { data; next = null; constructor(data) { this.data = data; } }; // append() 往链表尾部追加数据 append(data) { // 创建新的节点 const newNode = new this.Node(data); // 追加新的节点 if(this.length === 0) { // 链表只有长度为0时,在最后面添加新的节点 let currentNode = this.head;
// 当currentNode.next不为空时,循环依次找到最后一个节点,即节点的next为null时 while(currentNode.next !== null) { currentNode = currentNode.next; } // 最后一个节点的next指向新的节点 currentNode.next = newNode; } // 追加完新的节点之后,链表长度 +1 this.length++;} // toString() 方法 toString() { let currentNode = this.head; let result = ""; // 遍历所有节点,拼接为字符串,直到节点为null while(currentNode) { result += currentNode.data + ''; currentNode = currentNode.next; } return result; }
// 实现insert() 在指定位置的position插入节点 insert(position,data) { // position新插入节点的位置 // position = 0 表示新插入后的第一个节点 position = 1表示新插入后的第二个节点,以此类推 // 1,对position进行越界判断,不能小于0,或者大于链表的长度 if(position < 0 || position > this.length) return false; // 2,创建新的节点 const newNode = new this.Node(data); // 插入节点 if(position === 0) {// position = 0 的情况 // 让新节点的next指向,原来第一个节点,即head newNode.next = this.head;
// head 赋值为newNode this.head = newNode; }else { // 0 < position <= length的情况 // 初始化一些变量 let currentNode = this.head; // 当前节点初始化为head let previousNode = null; // head 的上一个节点为null let index = 0; // head 的index为0; // 在0 ~ position之间遍历,不断更新 currentNode和previousNode 直到找到要插入的位置 while(index++ < position) { previousNode = currentNode; currentNode = currentNode.next; } // 在当前节点和当前节点的上一个节点之间插入新的节点,即他们的改变指向 newNode.next = currentNode; previousNode.next = newNode; } // 更新链表的长度 this.length++; return newNode;} // 实现getData()方法 getData(position) { // 1, position越界判断 if(position < 0 || position >= this.length) return null; // 2,获取指定的position节点的data let currentNode = this.head; let index = 0; while(index++ < position) { currentNode = currentNode.next; } // 返回data return currentNode.data; }
// 实现indexOf() 方法 indexOf(data) 返回指定data的index,如果没有,返回-1 indexOf(data) { let currentNode = this.head; let index = 0; while(currentNode) { if(currentNode.data === data ) { return index; } currentNode = currentNode.next; index++; } return -1; } // 实现update()方法 update(position,data) update(position, data) { // 涉及到position都要进行越界判断 // 1,position越界判断 if(position < 0 || position >= this.length) return false;
//2,通过循环遍历,找到指定position的节点 let currentNode = this.head; let index = 0; while(index++ < position ){ currentNode = currentNode.next; } // 修改节点data currentNode.data = data; return currentNode;}
// removeAt(position) 删除指定位置的节点 removeAt(position) { // 判断是否越界 if(position < 0 || position >= this.length) return false; // 删除指定的position节点 let currentNode = this.head; if(position === 0) { // position > 0的情况 this.head = this.head.next; }else { // position > 0的情况 通过遍历,找到指定的position let previousNode = currentNode; let index = 0; while(index++ < position) { previousNode = currentNode; currentNode = currentNode.next; } // 让上一个节点next指向当前节点的next previousNode.next = currentNode.next; } // 更新链表的长度 -1 this.length--; return currentNode; }
// remove(data)删除指定data节点 remove(data) { this.removeAt(this.indexOf(data)) }
// 实现isEmpty()方法 isEmpty() { return this.length === 0; }
// 实现size() 方法 size() { return this.length; } }