数据结构之链表(三)

126 阅读2分钟

这是我参与更文挑战的第15天,活动详情查看:更文挑战

在任意位置插入一个元素

这次,我们来实现insert方法。使用这个方法可以在任意位置插入一个元素。这个方法接受两个参数:

  • position:要插入的位置。
  • element:要插入的项。
function LikedList () {
    // 节点类
    let Node = function (element) {
           this.element = element
           this.next = null
    }
    // 链表数量
    let length = 0 
    // 第一个节点的引用
    let head = null
    
    this.insert = function (position, element) {
        // 检查越界
        if(position >= 0 && position <= length) {
            // 生成要插入的节点
            let node = new Node(element)
            // 声明变量current用来表示后续循环迭代的当前节点,初始值为head即列表的第一个节点
            let current = head
            // previous当前节点的前一个节点,初始值为null,也就是说第一个节点current的前一个节点为空
            let previous = null
            // index表示循环到当前节点时在列表中所处的位置
            let index = 0
            if (position === 0) {
                 node.next = current
                 head = node
            } else {
                while (index++ < position) {
                    previous = current
                    current = current.next
                }
                node.next = current
                previous.next = node
            }
            // 更新列表的长度
            length++
            return true
        } else {
            return false
        }
    }
    

跟上一篇的removeAt方法的实现一样,首先我们需要检查传入的position是否越界,如果越界直接返回false,表示没有添加到项到列表中。

接下来我们需要处理不同的场景,即判断position插入的位置是在列表的起点还是在列表的尾部,或者是在列表的中间。

上述代码中,当position为0时,我们需要将上一步先生成的node项(要添加到列表中的项)的next属性值设置为current(即列表中第一个元素),此时,head和node.next都指向了current,那么就需要将head的引用改为node。即代表将node插入到了列表的第一个位置。

当position不为0时,我们需要循环列表找到目标位置。在循环体内将当前循环的项current赋值给previous,并将current项的值设置为cuurent.next以被下一次循环使用。当跳出循环体时即代表current将是对想要插入新元素的位置之后的一个元素的引用,而previous将是对想要插入新元素的的位置之前的一个元素的引用。在这种情况下,我们要在current和previous之间添加新项。所以,需要把新项即node的next指向current,并将previous的next指向node。

最后一定要记得更新列表的长度

未完待续下期来实现链表的其他方法