「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。
我个人觉得要想进大厂,就必须学习了解算法和数据结构,经历了多次面试之后,也知道了算法和数据结构的重要性,所以,我也打算从今天开始,进入学习,下载了一下电子书,边看书,边跟着书的例子来敲一下代码,下面就开始总结一下对算法和数据结构的学习吧。
第十三天:继续了解链表
前面,我们已经实现了链表类和节点类,还有在尾部添加节点的方法,下面我们来实现剩下的一些方法吧。
-
从链表中移除元素。
有两种从链表中移除节点的方法,一个是根据下标找到该节点,移除它,另一个是根据节点的值找到该节点并移除它,我们先实现根据下标找到节点并移除的方法。另一个方法之后就简单了
function removeAt(index) { // 首先是先处理边界值 if(index >= 0 && index < this.count) { let current = this.head // 如果是删除第一个节点 if(index === 0) { this.head = current.next }else { // 创建一个中间量,代表上一个 let previous for(let i = 0; i < index; i++) { previous = current current = current.next } // 隔开找到的那个值 previous.next = current.next } // 记得数量减一 this.count-- return current.element } // 如果传入的值是非法值,则直接返回undefined return undefined }如果是移除第一个节点,就是下面这个图

如果是移除后面的,就是下面这个两个图,第一个是移除最后一个,第二个是移除中间的节点,其实两个都是一样的原理。


-
找到目标位置
我们可以把上面寻找到previous节点的方法给抽离出来
function getElementAt(index) { if(index >= 0 && index < this.count) { let node for(let i = 0; i < index && node !== null; i++) { node = node.next } return node } return undefined }这样的话,我们的removeAt方法可以写成下面这样
function removeAt(index) { let current = this.head if(index === 0) { this.head = current.next }else { const previous = this.getElementAt(index - 1) current = previous.next previous.next = current.next } this.count-- return current.element } -
在任意位置插入节点
function insert(element, index) { // 还是和移除一样,判断边界值 if(index >= 0 && index < this.count) { const node = new Node(element) // 如果是插入第一个的操作 if(index === 0) { const current = this.head node.next = current this.head = node }else { // 插入其他位置的操作 const previous = this.getElementAt(index - 1) const current = previous.next node.next = current previous.next = node } this.count++ } // 如果输入违法索引,返回false,证明插入失败 return false }下面是插入第一个位置的操作图
下面是插入最后一个位置和其他任意位置的图,其他两个的操作原因完全一致
下面最后一个位置
下面是中间任意位置
-
indexOf
和数组的一样,根据输入的元素,找到该元素在链表中的索引,上面我们已经实现了根据索引找到该节点了,现在我们实现根据值找到该索引
function indexOf (element) { let current = this.head for(let i = 0; i < this.count && current !== null; i++) { if(element === current.element) { return i } current = current.next } return -1 } -
从链表中移除元素
有了indexOf和removeAt方法之后,要实现这个方法就简单了
function remove(element) { let index = this.indexOf(element) let current = this.removeAt(index) } -
还有一些比较简单实现的方法,和上面学习的栈、队列差不多
function isEmpty() { return this.head === null } function size() { return this.count } // 有了size,还可以直接这么实现isEmpty function isEmpty() { return this.size() === 0 } function getHead() { return this.head } -
最后一个toString
function toString() { if(this.head === null) return '' let current = this.head.next let stringRes = `${this.head.element}` for(let i = 1; i < this.count; i++) { stringRes = `${stringRes},${current.element}` current = current.next } return stringRes }