数据结构之链表(二)

148 阅读3分钟

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

从链表中移除元素

前一篇文章中,我们了解了链表以及向链表尾部添加元素,那么接下来我们实现从链表中移除元素。 移除元素有两种场景:

  • 移除第一个元素,是从特定位置移除一个元素。
  • 移除第一个以外的元素,是根据元素的值移除元素。
function LikedList () {
    // 节点类
    let Node = function (element) {
           this.element = element
           this.next = null
    }
    // 链表数量
    let length = 0 
    // 第一个节点的引用
    let head = null
    
    this.removeAt = function (position) {
        // 检查越界
        if (position > -1 && position < length) {
            let current = head
            let previous = null
            let index = 0
            // 移除第一项
            if (position === 0) {
                head = current.next
            } else {
                while (index++ < position) {
                    previous = current
                    current = current.next
                }
                // 将previous与current的下一项连接起来,跳过current从而移除它
                previous.next = current.next
            }
            length--
            return current.element
        } else {
            return null
        }
    }
    
}

上述代码中,我们要移除元素首先要明确该元素的位置即position,且需判断该position是否有效,若无效则返回null,而从0到列表的长度都是有效的位置。

如果position值为0,则移除第一个元素,此时我们要做的就是让head指向列表的第二个元素。我们用current变量创建一个对列表中第一个元素的引用,后续将用current来迭代列表。这样的话current变量就是对列表中第一个元素的引用。如果把head赋值为current.next就会移除第一个元素。(这段话的意思是head表示列表的第一个元素,创建变量current并将其值设置为head,那么此时current.next就是第二个元素,那么移除第一个元素实际上就是将head指向第二个元素。)

如果positon是列表的最后一项或者中间某一项。此时,需要依靠一个细节来迭代列表,直到到达目标位置(使用一个用于内部控制和递增的index变量),而current变量总是为对所循环列表的当前元素的引用,此外还需要一个对当前元素的前一个元素的引用,我们将其定义为previous。所以要从列表中移除当前元素就是将previous.next和current.next连接起来,这样的话,当前元素就会被丢弃在计算机内存中,等着被垃圾回收器清除。

首先考虑移除最后一个元素:对于最后一个元素来说,当我们跳出循环时,current变量将是对列表中最后一个元素的引用(要移除的元素)。current.next的值将是null。由于还保留了对前一个元素previous的引用,即previous.next指向current。那么要移除current就是将previous.next的值变为current.next,因为此时current.next的值将是null

对于移除列表中间元素来说:current变量是对要移除元素的引用,previous变量是对要移除元素的前一个元素的引用。那么要移除current元素就是将previous.next的值变为current.next

未完待续下期我们一起来了解:在任意位置插入一个元素