C# 链表LinkedList使用方法 C#如何使用双向链表

来源:这里教程网 时间:2026-02-21 17:41:00 作者:

LinkedList 初始化和基本增删操作

直接 new

LinkedList<t></t>
就能创建空双向链表,内部节点自带前后引用,不用手动维护指针。插入和删除在任意位置都是 O(1),但前提是得先拿到目标节点(
LinkedListNode<t></t>
),而不是靠索引——它不支持
[i]
访问。

常见误用:想用

list.AddLast(x)
后立刻
list[0]
取值,会编译失败。正确做法是用
list.First.Value
list.Last.Value
拿头尾元素。

AddFirst()
/
AddLast()
:插到头或尾,返回新节点(
LinkedListNode<t></t>
AddBefore(node, value)
/
AddAfter(node, value)
:必须传入已有节点,不是值或索引
Remove(node)
Remove(value)
:前者快且稳定;后者会遍历找第一个匹配值,找不到不报错,只返回 false
清空用
Clear()
,别用循环
RemoveFirst()
,性能差

如何安全获取和遍历 LinkedList 节点

遍历推荐用

foreach
直接枚举值:
foreach (var item in list) { ... }
。如果需要修改结构(比如边遍历边删),就不能用 foreach,得手动走节点链。

容易踩坑的是节点生命周期:一个

LinkedListNode<t></t>
只属于一个
LinkedList<t></t>
实例。把它从 A 链表
Remove()
后再塞进 B 链表,没问题;但如果没
Remove()
就直接
AddLast(node)
到另一个链表,会抛
InvalidOperationException
:“The node belongs to a different LinkedList.”

从值找节点用
Find(value)
,返回
LinkedListNode<t></t>
或 null
从节点取前后节点:用
node.Next
/
node.Previous
,为空时返回 null(不是异常)
遍历时删当前节点?必须先保存
node.Next
,再调
list.Remove(node)
,否则
node.Next
会变 null

LinkedList 和 List 的关键区别与选型建议

别因为“链表听起来高级”就默认选

LinkedList<t></t>
。它的内存开销大(每个元素额外两个引用字段 + 节点对象),缓存不友好,遍历速度远慢于
List<t></t>
。真正适合它的场景很窄:

频繁在头尾做插入/删除(比
List<t>.Insert(0, x)</t>
RemoveAt(0)
快得多)
需要在已知节点附近反复增删(比如实现 LRU 缓存,把刚访问的节点移到头) 不能接受
List<t></t>
扩容时的数组复制开销,且确定不会随机访问

如果只是偶尔插中间、大部分时间查第 i 个元素,或者数据量小(List 几乎总是更优。

常见错误:NullReferenceException 和 InvalidOperationException

两种异常最常出现在节点操作中:

NullReferenceException
:对 null 节点调
node.Value
node.Next
,比如
Find()
返回 null 后没判空就直接用
InvalidOperationException
:“The LinkedList node does not belong to this LinkedList.”——节点被重复添加,或从原链表移除前就被加到别的链表
InvalidOperationException
:“The LinkedList is empty.”——对空链表调
First
/
Last
属性(它们是 get-only,不抛异常,但值为 null;真要取值必须先判空)

安全写法是:所有通过

Find
First
Last
拿到的节点,使用前先
if (node != null)

相关推荐