—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——
接下来是方法 AddBefore() , 其和前两个方法一样,均有两个重载方法,主要是返回类型与参数不同 。
(1) 对于无返回值、待添加元素为链表(结点)的方法
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6422431-30.jpg)
文章插图
- Line 121:node 为目标结点,在其之后进行添加;newNode 为新结点 。
- Line 123、124:方法 ValidateNode() 与 ValidateNewNode() 用于判断 node 的合法性
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6423208-31.jpg)
文章插图
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6426191-32.png)
文章插图
是否为空;是否为该链表的成员(目的可能是防止多线程同步访问出现的错误调用)
- Line 125:方法 InternalInsertNodeBefore() 实现添加操作 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6426227-33.png)
文章插图
就是普通的双向链表的插入 。
(2) 对于返回类型为 LinkedList<T>,添加元素为某个值的方法
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6424Y5-34.png)
文章插图
- Line 132~134:判断 node 合法性;初始化一个以 node 为首 , node 值为 value的新链表;将新链表连接到 node 之前 。
- Line 137:当 node 为头结点时,添加后需要更新头结点 。
方法 AddAfter() 大同小异,不做过多分析
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6424H9-35.jpg)
文章插图
2. 包含 Contains() [ Find() 方法]
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://pic.ikafan.com/imgp/L3Byb3h5L2h0dHBzL2ltZzIwMjIuY25ibG9ncy5jb20vYmxvZy8yODUxNTQwLzIwMjIxMS8yODUxNTQwLTIwMjIxMTA4MTM1NTM0ODA2LTgzOTU1Mzk4LnBuZw==.jpg)
文章插图
方法套方法,Find 可以用来查找元素,其在其他的方法(如:Remove())中也可以使用,为了减少冗余,因此此处直接复用了方法 Find() 来实现 。
复用的思想在竞赛、开发中十分常用,既能有效减少工程量,还能提高代码可读性 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K642DK-37.png)
文章插图
- Line 270:Nullable 特性,其中 LinkedList 可为空;<T> 不可为空 。
- Line 277:next 表示当前即将访问的元素,从 head 开始 。
- Line 278:定义了一个默认比较方式的变量 , 用于之后调用比较方法 。EqualityCompare<T> 类型,一个抽象类,内部提供了一个 Equals() 方法,进行对象间的比较 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K642B59-38.jpg)
文章插图
【思考:为什么需要定义该类型的变量,调用该类中的比较方法 , 而不直接用判断运算符 “==” 或 Object.Equals() 方法?文末进行解释】
- Line 279:若 next 为空,即 head 为空,说明没有元素在链表中,则直接返回值为空的 next( Line: 304 ) 。
- Line 281:若要查找的对象值为空,则不进行比较操作 , 直接判断是否存在空元素 。
- Line 283:若当前结点值 item != value 则向后访问下一个结点 , 继续比较,直到找到符合的结点或再次访问到头结点 。
- Line 288、298:若没有找到符合的结点,则直接转调并返回 null 。
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6424U6-39.png)
文章插图
相比方法 Find(),只是将 next 换成了 prev,其他地方大同小异 , 主要来分析一下这个 prev 的作用 。
当 linkedListNode == prev 时,说明已经遍历完了一遍,此时还未找到目标元素,返回 null 。
4. 删除 Remove()
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K64243T-40.png)
文章插图
其基本思路说判断合法性,然后执行操作 。其中 ValidateNode 在之前提到过,用于判断结点合法性 。
下面看一下方法 InternalRemoveNode()
![.NET 源码学习 [数据结构-线性表1.2] 链表与 LinkedList<T>](http://img.zhejianglong.com/231019/1K6421561-41.png)
文章插图
和添加方法中的那个 InternalInsert…() 基本一致,改变结点的指向即可 , 记得最后要修改结点数量 。
推荐阅读
- MPC:百万富翁问题
- Redisson源码解读-公平锁
- 重新整理 .net core 实践篇 ———— dotnet-dump [外篇]
- PGL Paddle Graph Learning 关于图计算&图学习的基础知识概览:前置知识点学习
- .Net 7里的函数.Ctor和.CCtor是干啥用的呢?你知道吗
- OpenHarmony移植案例: build lite源码分析之hb命令__entry__.py
- 【深入浅出 Yarn 架构与实现】1-2 搭建 Hadoop 源码阅读环境
- 关于ASP.NET Core WebSocket实现集群的思考
- .NET周报【11月第1期 2022-11-07】
- JVM学习笔记——内存模型篇