目录
实现链表
实现思路
链表简介
说起链表来大家可能都听过,因为他的名气还不小。链表里面的数据在存储空间的分布是不连续的。这就给了它一个优势,即链表允许节点在链表的任意位置插入。虽然数组用来搜查数据很方便,但是只能把数据添加到数组的末尾,没有选择插入的余地。
不过不连续的分布也意味着我们需要在每个数据节点上做一个标识才能找到数据,同时我们需要一个链表头来确定该链表的开始位置。我们将这个标识称为指针,每一个节点都有一个指针,指向下一个节点。而为了操作方便,我们给链表头配置了一个头指针,并且还有一个临时指针,我们会通过它对目标节点并进行增删查操作。
![](https://img-blog.csdnimg.cn/62e56da322d24b8ebf980eebe62c4655.png)
节点里面有什么呢?节点包含数据项以及指向下一个节点。补充一下:由于在链表中,最后一个节点后面再没有节点,因此指向下一个节点的指针就是空指针null。在单链表的删除方法中我们还会见到它的。
头指针和伪头
有些读者可能会有一个想法:我们能不能让头指针成为临时指针,让他来遍历整个链表呢?这个想法是很好的,但是有些不现实。虽然每个节点都配有指针,但是我们实际上只知道头指针的位置——指向第一个节点。如果头指针自身变化了,如何才能找到第一个节点的位置呢?链表的数据在存储空间是分布的,一旦失去了我们能控制的指针,这数据就很难找到了。因此我们要重新创建一个临时指针,让他去遍历,而头指针尽量不动。
![](https://img-blog.csdnimg.cn/6b0bccbd3d084b538254970d4a0571d6.png)
我们简单讲一下实现单链表的两种思路。一种是带有伪头和链表头的实现,一种只有链表头,我们这次代码实现的是第一种。什么是伪头呢?伪头是一个位于链表头前面的节点,内置头指针且不存储数据。奇怪,明明已经有链表头了,为什么要伪头呢?由于头指针确定了一个链表,因此我们如果想删掉链表头,或在其前面插入节点时,就需要先将头指针转移到其他满足条件的节点,再进行操作,十分麻烦。
因为伪头只有头指针没有值,所以它自身是不参与链表的基本操作的,换句话说,所有的操作都在它的后面进行。因此,使用了伪头,我们在增删操作中就不需要移动头指针,而且链表头可以永久的确定为伪头的下一个节点。另外,基于伪头永久不变的特点,我们可以创建一个起始于伪头节点的临时指针,通过.next操作,轻而易举地到达单链表内所有节点。需要注意的是,伪头的索引值是-1,链表头的索引值才是0,也就是说,伪头在隐藏空间里。
前面讲到,由于伪头已经起到链表头的作用了,因此我们在程序中会把伪头