在C#中手动实现并遍历单链表是理解指针引用与集合操作的基础。单链表由一系列节点构成,每个节点保存自身数据与下一个节点的引用,遍历就是从头部开始逐个访问直到引用为空。

单链表的基本结构
我们可以先定义一个简单的泛型节点类与链表类,用于后续遍历演示。
// 定义单链表节点
public class ListNode<T>
{
public T Data { get; set; }
public ListNode<T> Next { get; set; }
public ListNode(T data)
{
Data = data;
Next = null;
}
}
// 简单的单链表封装
public class SingleLinkedList<T>
{
public ListNode<T> Head { get; set; }
public void Add(T data)
{
var newNode = new ListNode<T>(data);
if (Head == null)
{
Head = newNode;
return;
}
var current = Head;
while (current.Next != null)
{
current = current.Next;
}
current.Next = newNode;
}
}
使用while循环进行遍历
最直观的遍历方式是使用while循环,判断当前节点是否为空是最关键的一步,这样才能避免调用null的Next属性。
SingleLinkedList<int> list = new SingleLinkedList<int>();
list.Add(10);
list.Add(20);
list.Add(30);
ListNode<int> current = list.Head;
while (current != null)
{
Console.WriteLine(current.Data);
current = current.Next;
}
上面的代码从Head出发,只要current不是null就输出数据并移动到下一个节点,当current为null时自然结束循环,不会抛出空引用异常。
实现IEnumerable以支持foreach遍历
为了让单链表可以使用foreach语法,我们可以让链表类实现IEnumerable接口,并在GetEnumerator中复用安全的遍历逻辑。
using System;
using System.Collections;
using System.Collections.Generic;
public class SingleLinkedList<T> : IEnumerable<T>
{
public ListNode<T> Head { get; set; }
public void Add(T data)
{
var newNode = new ListNode<T>(data);
if (Head == null)
{
Head = newNode;
return;
}
var cur = Head;
while (cur.Next != null)
{
cur = cur.Next;
}
cur.Next = newNode;
}
public IEnumerator<T> GetEnumerator()
{
var current = Head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
有了上面的实现,就能用下面的方式遍历:
foreach (var item in list)
{
Console.WriteLine(item);
}
常见错误与注意事项
- 在循环条件中直接写
current.Next != null而未判断current本身是否为空,会在空链表时出错。 - 在遍历时修改链表结构(如删除节点)需要谨慎处理引用,否则容易丢失后续节点。
- 如果Head未被正确初始化,直接访问Head.Data也会引发异常,使用前要确保Head不为null。
遍历单链表的核心原则永远是:在访问节点的Next或Data之前,确认该节点引用不是null。
小结
使用C#进行单链表遍历并不复杂,只要掌握从Head出发、以当前节点是否为null作为循环边界,就能写出稳定安全的代码。进一步实现IEnumerable还可以让链表用上foreach,使调用端代码更简洁。