.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>( 五 )

—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——
接下来是方法 AddBefore() , 其和前两个方法一样,均有两个重载方法,主要是返回类型与参数不同 。
(1)   对于无返回值、待添加元素为链表(结点)的方法

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
  • Line 121:node 为目标结点,在其之后进行添加;newNode 为新结点 。
  • Line 123、124:方法 ValidateNode() 与 ValidateNewNode() 用于判断 node 的合法性

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
是否为空;是否为该链表的成员(目的可能是防止多线程同步访问出现的错误调用)
  • Line 125:方法 InternalInsertNodeBefore() 实现添加操作 。

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>

文章插图
就是普通的双向链表的插入 。
(2)   对于返回类型为 LinkedList<T>,添加元素为某个值的方法
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
  • Line 132~134:判断 node 合法性;初始化一个以 node 为首 , node 值为 value的新链表;将新链表连接到 node 之前 。
  • Line 137:当 node 为头结点时,添加后需要更新头结点 。
—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——
方法 AddAfter() 大同小异,不做过多分析
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
2.    包含 Contains() [ Find() 方法]
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
方法套方法,Find 可以用来查找元素,其在其他的方法(如:Remove())中也可以使用,为了减少冗余,因此此处直接复用了方法 Find() 来实现 。
复用的思想在竞赛、开发中十分常用,既能有效减少工程量,还能提高代码可读性 。
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
  • Line 270:Nullable 特性,其中 LinkedList 可为空;<T> 不可为空 。
  • Line 277:next 表示当前即将访问的元素,从 head 开始 。
  • Line 278:定义了一个默认比较方式的变量 , 用于之后调用比较方法 。EqualityCompare<T> 类型,一个抽象类,内部提供了一个 Equals() 方法,进行对象间的比较 。

.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
【思考:为什么需要定义该类型的变量,调用该类中的比较方法 , 而不直接用判断运算符 “==” 或 Object.Equals() 方法?文末进行解释】
  • Line 279:若 next 为空,即 head 为空,说明没有元素在链表中,则直接返回值为空的 next( Line: 304 ) 。
  • Line 281:若要查找的对象值为空,则不进行比较操作 , 直接判断是否存在空元素 。
  • Line 283:若当前结点值 item != value 则向后访问下一个结点 , 继续比较,直到找到符合的结点或再次访问到头结点 。
  • Line 288、298:若没有找到符合的结点,则直接转调并返回 null 。
3.    查找 FindLast()从方法名来看 , 其作用是找到值 value 在链表中出现的最后一次所对应的结点 。
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
相比方法 Find(),只是将 next 换成了 prev,其他地方大同小异 , 主要来分析一下这个 prev 的作用 。
当 linkedListNode == prev 时,说明已经遍历完了一遍,此时还未找到目标元素,返回 null 。
4.    删除 Remove()
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
其基本思路说判断合法性,然后执行操作 。其中 ValidateNode 在之前提到过,用于判断结点合法性 。
下面看一下方法 InternalRemoveNode()
.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList&lt;T&gt;

文章插图
和添加方法中的那个 InternalInsert…() 基本一致,改变结点的指向即可 , 记得最后要修改结点数量 。

推荐阅读