第一种 /** * 链表节点类 */ class Node { constructor(ele) { this.ele = ele; this.next = null; } } /** * 链表类 */ class NodeList { constructor(ele) { this.head = new Node(ele); //初始化链表的头节点 } findPreNode(item) { let currentNode = this.head; while (currentNode && currentNode.next && currentNode.next.ele !== item) { if (currentNode.next) { currentNode = currentNode.next; } else { currentNode = null; } } return currentNode; } findNode(item) { let currentNode = this.head; while (currentNode && currentNode.ele !== item) { if (currentNode.next) { currentNode = currentNode.next; } else { currentNode = null; } } return currentNode; } findLastNode() { let currentNode = this.head; while (currentNode.next) { currentNode = currentNode.next; } return currentNode; } append(newItem, preItem) { let newNode = new Node(newItem); if (preItem) { // 判读是否是插入到指定节点后面,如果不是则插入到最后一个节点。 let currentNode = this.findNode(preItem); newNode.next = currentNode.next; currentNode.next = newNode; } else { let lastNode = this.findLastNode(); lastNode.next = newNode; } } remove(item) { let preNode = this.findPreNode(item); // 找到前一节点,将前一节点的next指向该节点的next if (preNode.next != null) { preNode.next = preNode.next.next; } } toString() { let currentNode = this.head; let strList = []; while (currentNode.next) { strList.push(JSON.stringify(currentNode.ele)); currentNode = currentNode.next; } strList.push(JSON.stringify(currentNode.ele)); return strList.join(' ==> ') }
/* 逆置分析
单链表分为带头节点和不带头节点两种,逆置思路有两种,第一种是采用头插法重新建立新的单链表,该方法直接遍历链表,每次将当前结点添加到新链表的头部;第二种是通过该表*next指针,定义三个指针*pre, *p, *r,分别表示三个连续结点,将p->next指向pre,但 同时p的后继节点会断开,所以需要用r保存其后继节点。
*/
// 头插法 reverse () { let p = null; let current = this.head; while (current !== null) { const temp = current.next; current.next = p; p = current; current = temp; } return p; } // 1 -> 2 -> 3 -> 4 // r // 修改*next指针 reverse2 () { let pre = null; let p = null; let r = null; r = this.head; while (r !== null) { if (p === null) { p = r; r = r.next; p.next = null; continue; } pre = p; p = r; r = r.next; p.next = pre; } return p; } } let A = { name: 'A', age: 10 }, B = { name: 'B', age: 20 }, C = { name: 'C', age: 30 }, D = { name: 'D', age: 40 }, E = { name: 'E', age: 50 }; let nList = new NodeList(A); nList.append(C); nList.append(B); nList.append(D); nList.append(E, A); console.log(" " + nList); nList.remove(C); console.log(" now " + nList)
origin: {"name":"A","age":10} ==> {"name":"E","age":50} ==> {"name":"C","age":30} ==> {"name":"B","age":20} ==> {"name":"D","age":40}
now: {"name":"A","age":10} ==> {"name":"E","age":50} ==> {"name":"B","age":20} ==> {"name":"D","age":40}
第二种 /** * 链表节点类 */ class Node { constructor (ele) { this.ele = ele; this.next = null; } } /** * 链表类 */ class NodeList { constructor (ele) { this.head = null; // 初始化链表的头节点 this.lenght = 0; } /** * 尾部插入数据 * @param {*} ele */ append (ele) { let newNode = new Node(ele); let currentNode; if (this.head === null) { this.head = newNode; } else { currentNode = this.head; while (currentNode.next) { currentNode = currentNode.next; } currentNode.next = newNode; } this.lenght++; }/** * 项链表某个位置插入元素 * @param {*} position * @param {*} ele */ insert (position, ele) { if (position >= 0 && position <= this.lenght) { let newNode = new Node(ele); let currentNode = this.head; let pre; let index = 0; if (position === 0) { newNode.next = currentNode; this.head = newNode; } else { while (index < position) { pre = currentNode; currentNode = currentNode.next; index++; } newNode.next = currentNode; pre.next = newNode; } this.lenght++; } else { return new Error('位置超出范围'); } } removeAt (position) { if (position >= 0 && position < this.lenght) { let currentNode = this.head; let pre; let index = 0; if (position === 0) { this.head = currentNode.next; } else { while (index < position) { // 1,2,3 pre = currentNode; currentNode = currentNode.next; index++; } pre.next = currentNode.next; } this.lenght--; } else { return new Error('删除位置有误'); } } find (ele) { let currentNode = this.head; let index = 0; while (currentNode) { if (JSON.stringify(currentNode.ele) === JSON.stringify(ele)) { return index; } else { index++; currentNode = currentNode.next; } } return -1; } // 判断链表是否为空 isEmpty () { return this.length === 0; } size () { return this.length; } // 返回头 getHead () { return this.head; } toString () { let current = this.head; let str = ''; while (current) { str += JSON.stringify(current.ele) + ' => '; current = current.next; } return str; } } let A = { name: 'A', age: 10 }; let B = { name: 'B', age: 20 }; let C = { name: 'C', age: 30 }; let D = { name: 'D', age: 40 }; let E = { name: 'E', age: 50 }; let nList = new NodeList(); nList.append(A); nList.append(C); nList.append(B); nList.append(D); nList.append(E); // console.log(JSON.stringify(nList, null, 2)); console.log(' origin: ' + nList); nList.removeAt(2); console.log(' now: ' + nList);
origin: {"name":"A","age":10} => {"name":"C","age":30} => {"name":"B","age":20} => {"name":"D","age":40} => {"name":"E","age":50} =>
now: {"name":"A","age":10} => {"name":"C","age":30} => {"name":"D","age":40} => {"name":"E","age":50} =>
参照:https://blog.csdn.net/qq_40941722/article/details/94381637