这是我参与更文挑战的第13天,活动详情查看:更文挑战
什么是链表
链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。 如下图所示:
- 相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。
- 链表需要使用指针,因此实现链表时需要额外主要。
- 想要访问链表中间的一个元素时,需要从起点(表头)开始迭代链表直到找到所需的元素。 链表类似于火车的结构,每节车厢都相互连接,很容易的分离一节车厢,改变它的位置,添加或者移除它。
创建链表
实现LinkedList类,LinkedList数据结构需要 一个Node辅助类,用来表示要加入列表的项。它包含一个elemengt属性,即要添加到列表的值,以及一个next属性即指向列表下一个节点项的指针。 LikedList类也有存储列表的数量的length属性(内部私有变量)。此外,我们还需要存储第一个节点的引用,可以将这个引用存储在一个head变量中。链表所需的方法如下:
- append(element): 向列表尾部添加一个新的项。
- insert(position, element): 向列表的特定位置插入一个新的项。
- remove(element): 从列表中移除一项。
- indexOf(element): 返回元素在列表中的索引。如果列表中没有该元素则返回-1
- removeAt(position): 从列表的特定位置移除一项。
- isEmpty(): 如果列表中不包含任何元素,返回true,如果链表的长度大于0则返回false
- size(): 返回链表中包含的元素个数,与数组的length属性类似。
- toString(): 由于列表项使用了Node类,就需要重写继承自js对象默认的toString方法,让其只输出元素的值。 实现向链表尾部添加元素
function LikedList () {
// 节点类
let Node = function (element) {
this.element = element
this.next = null
}
// 链表数量
let length = 0
// 第一个节点的引用
let head = null
// 向列表尾部添加一个新的项
this.append = function (element) {
// 尾部添加一个元素时,有两种情况:列表为空,添加的时第一个元素,或者列表不为空,向其追加元素
let node = new Node(element)
let current = null;
if (head === null) {
head = node
} else {
current = node
// 循环列表,直到找到最后一项
while(current.next) {
current = current.next
}
// 找到最后一项,将其next赋值为node建立连接
current.next = node
}
length++
}
// this.insert = function (position, element) {}
// this.removeAt = function (position) {}
// this.remove = function (element) {}
// this.indexOf = function (element) {}
// this.isEmpty = function () {}
// this.size = function () {}
// this.getHead = function () {}
// this.toString = function () {}
// this.print = function () {}
}
PS:列表最后一个节点的下一个元素始终是null
上述代码中,实现步骤如下:
- 首先将element作为值传入,创建Node项。并记录current
- 当新建一个LinkedList对象时,head会指向null,如果head为null则是在向列表添加第一个元素,此时我们要做的就是将上一步创建的node赋值给head
- head不为空时,要向列表尾部添加一个元素,那么首先就得找到最后一个元素。
- 循环访问列表,直到找到最后一项,此时首先定一个current变量表示循环的当前项,初始值为head,即从头开始循环。
- 如果current.next不为nul,说明其不是最后一个元素,那么将current.next赋值给current,即将current循环到下一项。
- 如果current.next为null,说明已经找到了最后一项,也就是此时的current,那么将current.next的值指向要添加进来的元素node,即可。
- 到第六步结束,我们已经将node添加到了列表的尾部,但是不要忘记了更新长度length
- 完美结束。
未完待续。。。 下期更新从链表中移除元素