1

I am implementing a Graph via adjacency list, and I am trying to add a node to a Graph class but I keep getting an error

System.NullReferenceException has been thrown

this is the bit of my code:

MyNode class

    class node
    {
        public List<object>? Neighbors { get; set; }
        public int Data { get; set; }

        public node() { }
        public node(int val)
        {
            Data = val;
        }
    }

This is my graph class:

class Graph
    {
        // Attributes of the Class
        public int NumVertices { get; set; }       // Number of vertices
        public List<node> vertices { get; set; }           // list of nodes in the graph

        // Graph constructor
        public Graph(int size)
        {
            NumVertices = size;
            vertices = new List<node>();
            //// Allocate node objects at each index of the vertice list
            //for (int i = 0; i < NumVertices; i++)
            //{
            //    Instantiate(vertices[i]); 
            //}
        }

        //Adding ege to vertice
        public void addEdge(node a, node b)
        {
            a.Neighbors.Add(b);   //---> it referenced here
            b.Neighbors.Add(a);
        }

Then testing functions: this Instantiates node objects and

public static void TestGraph()
        {
            node a = new node(1);
            node b = new node(2);
            node c = new node(3);
            node d = new node(4);
            node e = new node(5);
            node f = new node(6);

            Graph myGraph = new Graph(6) ;
            //// Add vertices to the node
            //myGraph.vertices.Add(a);
            //myGraph.vertices.Add(b);
            //myGraph.vertices.Add(c);
            //myGraph.vertices.Add(d);
            //myGraph.vertices.Add(e);
            ////myGraph.vertices.Add(f);

            myGraph.addEdge(a, b);   //---> Error originates here
            myGraph.addEdge(a, c);
            myGraph.addEdge(a, d);
            myGraph.addEdge(b, c);
            myGraph.addEdge(c, e);
            myGraph.addEdge(d, e);

            Console.WriteLine("Cheching if a and b are neighbors " + myGraph.isAdjacent(a, b).ToString());
            Console.WriteLine("Cheching if a and c are neighbors " + myGraph.isAdjacent(a, c).ToString());

How would I be able to rectify this issues? Thanks

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • 1
    Run your code with a debugger to find out where exactly the exception is thrown. Look at the variable values just before the exception occurs. Usually, this will make the error obvious. – ravenspoint Sep 03 '22 at 18:15

3 Answers3

1

There is no problem with the node object but it's Neighbors field which is supposed to be a List but the constructor doesn't have any initialization for it.

If you change your constructors to initialize Neighbors, the null reference error will go away. Below is an example to how you can initialize the list.

    public node(int val)
    {
        Data = val;
        Neighbors = new List<object>();
    }
1

You have never created a Neighbors list, so it will always be null.

I would formulate those lists as getter-only properties with an initializer. Then the lists get initialized automatically and you can't forget to do it later.

class Node
{
    public List<Node> Neighbors { get; } = new();
    public int Data { get; set; }

    public Node() { }

    public Node(int val)
    {
        Data = val;
    }
}

Also, this must be a List<Node>, not a List<object>, since you will always add nodes to it. Alternatively, the Neighbors list could also be a List<int> storing the indices of the neighbors in the Graph.Vertices list instead of the nodes themselves.

Graph has a property public int NumVertices { get; set; }. Isn't NumVertices equivalent to Vertices.Count? Since you pass the graph size to the constructor, it makes sense to add this number of nodes the Vertices list in the constructor. NumVertices then automatically matches this size since it returns Vertices.Count.

class Graph
{
    public int NumVertices => Vertices.Count;
    public List<Node> Vertices { get; } = new();

    public Graph(int size)
    {
        for (int i = 0; i < size; i++) {
            Vertices.Add(new Node());
        }
    }

    public void AddEdge(int i, int j)
    {
        Node a = Vertices[i];
        Node b = Vertices[j];
        a.Neighbors.Add(b);
        b.Neighbors.Add(a);
    }

    public bool AreAdjacent(int i, int j)
    {
        return Vertices[i].Neighbors.Contains(Vertices[j]);
    }
}

Since the nodes are stored in the Graph object, it makes sense to pass their index in the AddEdge and AreAdjacent methods instead of keeping another reference of them outsize of Graph object. This is better for consistency, as it is only possible to add edges between nodes that are actually in this graph.

Adding edges:

var graph = new Graph(6);
graph.AddEdge(0, 1);
graph.AddEdge(0, 2);
graph.AddEdge(0, 3);
graph.AddEdge(1, 2);
graph.AddEdge(2, 4);
graph.AddEdge(3, 4);
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0
  myGraph.addEdge(a, b);   //---> Error originates here

So, what is the value of a? Your posted code leaves it uninitialized.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103