模拟链表
class Node {constructor(value) {this.value = value;this.next = null;}}class LinkedList {constructor() {this.length = 0;this.head = null;}equalsFn(a, b) {return a === b;}}
功能
- push(element):向链表尾部添加一个新元素。
- insert(element, position):向链表的特定位置插入一个新元素。
- getElementAt(index):返回链表中特定位置的元素。如果链表中不存在这样的元素,则返回undefined。
- remove(element):从链表中移除一个元素。
- indexOf(element):返回元素在链表中的索引。如果链表中没有该元素则返回-1。
- removeAt(position):从链表的特定位置移除一个元素。
- isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0 则返回false。
- size():返回链表包含的元素个数,与数组的length 属性类似。
- toString():返回表示整个链表的字符串。由于列表项使用了Node 类,就需要重写继承自JavaScript 对象默认的toString 方法,让其只输出元素的值。
push
push(val) {let newNode = new Node(val);let curr;if (!this.head) { // 刚开始链表为空,就把这个设置为headthis.head = newNode;} else {curr = this.head;while (curr.next) { // 一直找到链表末尾curr = curr.next;}curr.next = newNode;}this.length++;}
removeAt

removeAt(index) {if (index < this.length && index >= 0) {let curr = this.head;if (index === 0) {this.head = curr.next;} else {// 找到index前一个后停止,下一个就是要删除的结点for (let i = 1; i < index; i++) {curr = curr.next;}let beRemove = curr.next;// 改变要被删除结点的上一个结点的指向curr.next = beRemove.next;this.length--;return beRemove;}}}
getElementAt
getElementAt(index) {if (index < this.length && index >= 0) {let curr = this.head;if (index === 0) return curr;else {for (let i = 1; i <= index; i++) {curr = curr.next;}return curr;}}}
重写removeAt
removeAt(index) {let curr = this.getElementAt(index - 1);curr.next = curr.next.next;
insert

insert(index, value) {let newNode = new Node(value);if (index < this.length && index >= 0) {let curr = this.head;if (index === 0) { // index 为0,改变头结点指向就行了this.head = newNode;this.head.next = curr;} else {// 找到插入位置的前一个,for (let i = 1; i < index; i++) {curr = curr.next;}let nextNode = curr.next;curr.next = newNode;newNode.next = nextNode;}this.length++;}}
indexOf
indexOf(value) {let curr = this.head; // 存入headif (this.equalsFn(curr.value, value)) {return 0;}for (let i = 1; i < this.length; i++) {curr = curr.next;if (this.equalsFn(curr.value, value)) {return i;}}return -1;}
removeValue
removeValue(value) {let curr = this.head;let prev = null;if (this.equalsFn(curr.value, value)) {this.head = curr.next;this.length--;}for (let i = 1; i < this.length; i++) {prev = curr;curr = curr.next;if (this.equalsFn(curr.value, value)) {prev.next = curr.next;this.length--;}}return undefined;}
toString
toString() {let objString = "";let curr = this.head;if (!curr) {return objString;} else {objString = `${curr.value}`;for (let i = 1; i < this.length; i++) {curr = curr.next;objString = `${objString}, ${curr.value}`;}return objString;}}
完整代码
class Node {constructor(value) {this.value = value;this.next = null;}}class LinkedList {constructor() {this.length = 0;this.head = null;}equalsFn(a, b) {return a === b;}push(val) {let newNode = new Node(val);let curr;if (!this.head) { // 刚开始链表为空,就把这个设置为headthis.head = newNode;} else {curr = this.head;while (curr.next) { // 一直找到链表末尾curr = curr.next;}curr.next = newNode;}this.length++;}removeAt(index) {let curr = this.getElementAt(index - 1);curr.next = curr.next.next;}getElementAt(index) {if (index < this.length && index >= 0) {let curr = this.head;if (index === 0) return curr;else {for (let i = 1; i <= index; i++) {curr = curr.next;}return curr;}}}insert(index, value) {let newNode = new Node(value);if (index < this.length && index >= 0) {let curr = this.head;if (index === 0) { // index 为0,改变头结点指向就行了this.head = newNode;this.head.next = curr;} else {// 找到插入位置的前一个,for (let i = 1; i < index; i++) {curr = curr.next;}let nextNode = curr.next;curr.next = newNode;newNode.next = nextNode;}this.length++;} else {throw "索引值错误";}}indexOf(value) {let curr = this.head; // 存入headif (this.equalsFn(curr.value, value)) {return 0;}for (let i = 1; i < this.length; i++) {curr = curr.next;if (this.equalsFn(curr.value, value)) {return i;}}return -1;}removeValue(value) {let curr = this.head;let prev = null;if (this.equalsFn(curr.value, value)) {this.head = curr.next;this.length--;}for (let i = 1; i < this.length; i++) {prev = curr;curr = curr.next;if (this.equalsFn(curr.value, value)) {prev.next = curr.next;this.length--;}}return undefined;}toString() {let objString = "";let curr = this.head;if (!curr) {return objString;} else {objString = `${curr.value}`;for (let i = 1; i < this.length; i++) {curr = curr.next;objString = `${objString}, ${curr.value}`;}return objString;}}getHead() {return this.head;}isEmpty() {return this.length === 0 ? true : false;}size() {return this.length;}}let linkedList = new LinkedList();linkedList.push("a");linkedList.push("b");linkedList.push("c");// linkedList.removeAt(1);linkedList.insert(1, "aa");console.log(linkedList.getElementAt(2));console.log(linkedList.indexOf("a"));console.log(linkedList.removeValue("c"));console.log(linkedList.size());console.log(linkedList.isEmpty());console.log(linkedList);console.log(linkedList.toString());
题目
lc237:删除链表中的结点
var deleteNode = function(node) {node.val = node.next.val;node.next = node.next.next;};
206. 反转链表
- 双指正法
- 最开始p1指向head,p2指向前一个null
- 改变p1.next,主意首先保存temp = p1.next;
- 改变p2 = p1,p1 = temp,双指针向前移动,直到p1为null
- 返回p2,此时p2为新的head
var reverseList = function(head) {let p1 = head;let p2 = null;while(p1) {const temp = p1.next;p1.next = p2;p2 = p1;p1 = temp;}return p2;};
2. 两数相加
var addTwoNumbers = function (l1, l2) {const l3 = new ListNode(0);let p1 = l1, p2 = l2;let p3 = l3;let carry = 0; // 上一步的进位while(p1 || p2) {const val1 = p1 ? p1.val : 0;const val2 = p2 ? p2.val : 0;const x = val1 + val2 + carry;carry = Math.floor(x / 10);p3.next = new ListNode(x % 10);if (p1) p1 = p1.next;if (p2) p2 = p2.next;p3 = p3.next;}if (carry) {p3.next = new ListNode(carry)}return l3.next;};
83. 删除排序链表中的重复元素
var deleteDuplicates = function(head) {let p = head;while(p && p.next) {if (p.val === p.next.val) {p.next = p.next.next;} else {p = p.next;}}return head;};
141. 环形链表
快慢指针
var hasCycle = function(head) {let p1 = head;let p2 = head;while(p1 && p2 && p2.next) {p1 = p1.next;p2 = p2.next.next;if (p1 === p2) {return true}}return false};
利用链表获取JSON的结点值
const json = {a: { b: { c: 1 } },d: { e: 2 },};// 写出结点的路径const path = ["a", "b", "c"];let p = json;path.forEach(k => {p = p[k];});console.log(p)
