You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现树的广度优先搜索(BFS)遇空引用异常,求排查修复

问题分析与修复

错误原因

你遇到的Object reference not set to an instance of object是C#中常见的空引用错误——当尝试访问null对象的属性或方法时就会触发。你的代码存在两个核心问题:

1. 硬编码匹配字符串,找不到目标节点

在NodeExtension.BFS方法中,你写了:

Node source = root.Child.Where(x => x.NodeName == "name").FirstOrDefault();

这里用了固定字符串"name",而非传入的方法参数name。调用t.root.BFS("C")时,代码会寻找节点名为"name"的子节点,而非"C",自然找不到目标节点,source变为null,后续执行source.visited = true就触发了空引用错误。

2. visited属性实现完全错误

你的Node类里的visited属性:

public bool visited { get { return false; } set { visited = value; } }
  • get方法永远返回false,无法正确获取节点的访问状态
  • set方法递归给自身赋值,会直接导致栈溢出异常,且永远无法正确标记节点为已访问

修复后的完整代码

using System;
using System.Collections.Generic;
using System.Linq;

public class Node
{
    // 私有字段存储访问状态
    private bool _visited;
    public string NodeName { get; set; }
    // 正确实现Visited属性
    public bool Visited 
    { 
        get { return _visited; } 
        set { _visited = value; } 
    }
    public LinkedList<Node> _item;
    public Node()
    {
        _item = new LinkedList<Node>();
    }
    public LinkedList<Node> Child { get { return _item; } set { _item = value; } }
}

public class Tree
{
    public Node root;
    public Tree()
    {
        root = new Node { NodeName = "A" };
    }
}

public static class NodeExtension
{   
    public static void BFS(this Node root, string name)
    {
        // 使用传入的name参数匹配节点
        Node source = root.Child.Where(x => x.NodeName == name).FirstOrDefault();
        
        // 先判断source是否为null,避免空引用
        if (source == null)
        {
            Console.WriteLine($"找不到节点名为{name}的子节点");
            return;
        }
        
        Queue<Node> queue = new Queue<Node>();
        source.Visited = true;
        queue.Enqueue(source);
        
        while (queue.Any())
        {
            Node u = queue.Dequeue(); // 直接Dequeue,无需先First再Dequeue,提升效率
            Console.WriteLine(u.NodeName);
            
            foreach (Node v in u.Child)
            {
                if (!v.Visited)
                {
                    v.Visited = true;
                    queue.Enqueue(v);
                }
            }
        }
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        Tree t = new Tree();
        t.root.Child.AddLast(new Node { NodeName = "B" });
        Node C = new Node { NodeName = "C" };
        C.Child.AddLast(new Node { NodeName = "D" });
        t.root.Child.AddLast(C);
        t.root.BFS("C");
    }
}

额外优化点

  • 将visited改为首字母大写的Visited,符合C#命名规范
  • BFS循环中直接用queue.Dequeue()获取节点,减少冗余操作
  • 增加节点不存在的判断逻辑,避免空引用同时给出友好提示

内容的提问来源于stack exchange,提问作者Nguyễn Nguyễn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:15:43