Adjacency list graph in Java











up vote
1
down vote

favorite












I am reading a text, that from a higher level explained adjacency list implementation of a graph.



I have now tried to implement this as simply as I could. I did not see any reason to have an actual vertex or node class.



Based on my implementation, does it look like I understood properly how an adjacency list graph works?



import java.util.*;

public class Graph {
private HashMap<String, HashSet<String>> nodes;

public Graph ()
{
nodes = new HashMap<String, HashSet<String>>();
}

public void addNode(String name)
{
if (!nodes.containsKey(name))
nodes.put(name , new HashSet<String>());
}

public void addEdge(String src , String dest)
{
HashSet<String> adjList = nodes.get(src);

if (adjList == null)
throw new RuntimeException("addEdge - src node does not exist");

adjList.add(dest);
}
}









share|improve this question














bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.











  • 1




    Can you include a main() that exercises this code? It's not obvious how you can use the generated graph.
    – Toby Speight
    Aug 27 at 7:39















up vote
1
down vote

favorite












I am reading a text, that from a higher level explained adjacency list implementation of a graph.



I have now tried to implement this as simply as I could. I did not see any reason to have an actual vertex or node class.



Based on my implementation, does it look like I understood properly how an adjacency list graph works?



import java.util.*;

public class Graph {
private HashMap<String, HashSet<String>> nodes;

public Graph ()
{
nodes = new HashMap<String, HashSet<String>>();
}

public void addNode(String name)
{
if (!nodes.containsKey(name))
nodes.put(name , new HashSet<String>());
}

public void addEdge(String src , String dest)
{
HashSet<String> adjList = nodes.get(src);

if (adjList == null)
throw new RuntimeException("addEdge - src node does not exist");

adjList.add(dest);
}
}









share|improve this question














bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.











  • 1




    Can you include a main() that exercises this code? It's not obvious how you can use the generated graph.
    – Toby Speight
    Aug 27 at 7:39













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I am reading a text, that from a higher level explained adjacency list implementation of a graph.



I have now tried to implement this as simply as I could. I did not see any reason to have an actual vertex or node class.



Based on my implementation, does it look like I understood properly how an adjacency list graph works?



import java.util.*;

public class Graph {
private HashMap<String, HashSet<String>> nodes;

public Graph ()
{
nodes = new HashMap<String, HashSet<String>>();
}

public void addNode(String name)
{
if (!nodes.containsKey(name))
nodes.put(name , new HashSet<String>());
}

public void addEdge(String src , String dest)
{
HashSet<String> adjList = nodes.get(src);

if (adjList == null)
throw new RuntimeException("addEdge - src node does not exist");

adjList.add(dest);
}
}









share|improve this question













I am reading a text, that from a higher level explained adjacency list implementation of a graph.



I have now tried to implement this as simply as I could. I did not see any reason to have an actual vertex or node class.



Based on my implementation, does it look like I understood properly how an adjacency list graph works?



import java.util.*;

public class Graph {
private HashMap<String, HashSet<String>> nodes;

public Graph ()
{
nodes = new HashMap<String, HashSet<String>>();
}

public void addNode(String name)
{
if (!nodes.containsKey(name))
nodes.put(name , new HashSet<String>());
}

public void addEdge(String src , String dest)
{
HashSet<String> adjList = nodes.get(src);

if (adjList == null)
throw new RuntimeException("addEdge - src node does not exist");

adjList.add(dest);
}
}






java graph






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 26 at 23:50









ScottF

1061




1061





bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.










  • 1




    Can you include a main() that exercises this code? It's not obvious how you can use the generated graph.
    – Toby Speight
    Aug 27 at 7:39














  • 1




    Can you include a main() that exercises this code? It's not obvious how you can use the generated graph.
    – Toby Speight
    Aug 27 at 7:39








1




1




Can you include a main() that exercises this code? It's not obvious how you can use the generated graph.
– Toby Speight
Aug 27 at 7:39




Can you include a main() that exercises this code? It's not obvious how you can use the generated graph.
– Toby Speight
Aug 27 at 7:39










1 Answer
1






active

oldest

votes

















up vote
0
down vote













I think the code is incomplete. It's possible to build a Graph but there is no way to process it as there are no methods returning the state of a Graph.



To be able to evaluate the shown code I'm going to extend it by two methods:



/**
* Returns true if a node with the given name was added.
*/
public boolean hasNode(String name) {
return nodes.containsKey(name);
}


/**
* Returns true if an edge form source node to destination node (identified by their names) was added.
*/
public boolean hasEdge(String src, String dest) {
HashSet<String> adjList = nodes.get(src);
return adjList != null && adjList.contains(dest);
}


Let's use a simple example to show some shortcomings:



public static void main(String args) {
Graph g = new Graph();
g.addNode("A");
g.addEdge("A", "B");

System.out.println(g.hasNode("A")); // true
System.out.println(g.hasNode("B")); // false
System.out.println(g.hasEdge("A", "B")); // true
}


egdes to missing nodes

The method addEdge verifies that a source node is already present. But it doensn't verify if the destination node is present, too. Thus it's possible to addEdge from an already added node to an unknown node.

Whereas hasNode("B") will state that there is no node "B" in the Graph g, hasEdgde("A", "B") will return true which is at least misleading. I think it's inconsistent as I would expected this implies there is a node "B" also present in the Graph g.



directed graph

Since addEdge adds an edge from a source node to a destination node it's more precise to speak of a directed graph. Otherwise



g.hasEdge("B", "A");


needs to return true. But actually it isn't.



readding a node is possbile

Another point: It's possible to add already added nodes again.



g.addNode("A");


This results in replacing the current node by a new one. There is no exception and hasNode("A") will still return true. But all edges from the previous node to other nodes are lost.



System.out.println(g.hasEdge("A", "B")); // false


This should be prevented.



readding an edge

Readding an edge doesn't throw an exception. But it doesn't add an edge actually. It's impossible since a node is storing it's edges in a Set. A Set will not add an already present element once again. As long as there is no need to know how many times an edge from a node to another was add this isn't severe.



Some further hints:




  • You can declare nodes as Map<String, Set<String>>. Since you're using interface methods only, there is no need to use the implementation types.

  • When adding a node calling first nodes.containsKey(name) and then on success calling nodes.put(name, new HashSet<String>()) has double complexity as the element within the map has to be looked up twice. But sinnce adding a node several times shouldn't be possible we can write


instead:



public void addNode(String name) {
Set<String> node = nodes.get(name);
if (node != null)
throw new RuntimeException("addNode - node already exist");
nodes.put(name, new HashSet<String>());
}





share|improve this answer





















    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f202540%2fadjacency-list-graph-in-java%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    I think the code is incomplete. It's possible to build a Graph but there is no way to process it as there are no methods returning the state of a Graph.



    To be able to evaluate the shown code I'm going to extend it by two methods:



    /**
    * Returns true if a node with the given name was added.
    */
    public boolean hasNode(String name) {
    return nodes.containsKey(name);
    }


    /**
    * Returns true if an edge form source node to destination node (identified by their names) was added.
    */
    public boolean hasEdge(String src, String dest) {
    HashSet<String> adjList = nodes.get(src);
    return adjList != null && adjList.contains(dest);
    }


    Let's use a simple example to show some shortcomings:



    public static void main(String args) {
    Graph g = new Graph();
    g.addNode("A");
    g.addEdge("A", "B");

    System.out.println(g.hasNode("A")); // true
    System.out.println(g.hasNode("B")); // false
    System.out.println(g.hasEdge("A", "B")); // true
    }


    egdes to missing nodes

    The method addEdge verifies that a source node is already present. But it doensn't verify if the destination node is present, too. Thus it's possible to addEdge from an already added node to an unknown node.

    Whereas hasNode("B") will state that there is no node "B" in the Graph g, hasEdgde("A", "B") will return true which is at least misleading. I think it's inconsistent as I would expected this implies there is a node "B" also present in the Graph g.



    directed graph

    Since addEdge adds an edge from a source node to a destination node it's more precise to speak of a directed graph. Otherwise



    g.hasEdge("B", "A");


    needs to return true. But actually it isn't.



    readding a node is possbile

    Another point: It's possible to add already added nodes again.



    g.addNode("A");


    This results in replacing the current node by a new one. There is no exception and hasNode("A") will still return true. But all edges from the previous node to other nodes are lost.



    System.out.println(g.hasEdge("A", "B")); // false


    This should be prevented.



    readding an edge

    Readding an edge doesn't throw an exception. But it doesn't add an edge actually. It's impossible since a node is storing it's edges in a Set. A Set will not add an already present element once again. As long as there is no need to know how many times an edge from a node to another was add this isn't severe.



    Some further hints:




    • You can declare nodes as Map<String, Set<String>>. Since you're using interface methods only, there is no need to use the implementation types.

    • When adding a node calling first nodes.containsKey(name) and then on success calling nodes.put(name, new HashSet<String>()) has double complexity as the element within the map has to be looked up twice. But sinnce adding a node several times shouldn't be possible we can write


    instead:



    public void addNode(String name) {
    Set<String> node = nodes.get(name);
    if (node != null)
    throw new RuntimeException("addNode - node already exist");
    nodes.put(name, new HashSet<String>());
    }





    share|improve this answer

























      up vote
      0
      down vote













      I think the code is incomplete. It's possible to build a Graph but there is no way to process it as there are no methods returning the state of a Graph.



      To be able to evaluate the shown code I'm going to extend it by two methods:



      /**
      * Returns true if a node with the given name was added.
      */
      public boolean hasNode(String name) {
      return nodes.containsKey(name);
      }


      /**
      * Returns true if an edge form source node to destination node (identified by their names) was added.
      */
      public boolean hasEdge(String src, String dest) {
      HashSet<String> adjList = nodes.get(src);
      return adjList != null && adjList.contains(dest);
      }


      Let's use a simple example to show some shortcomings:



      public static void main(String args) {
      Graph g = new Graph();
      g.addNode("A");
      g.addEdge("A", "B");

      System.out.println(g.hasNode("A")); // true
      System.out.println(g.hasNode("B")); // false
      System.out.println(g.hasEdge("A", "B")); // true
      }


      egdes to missing nodes

      The method addEdge verifies that a source node is already present. But it doensn't verify if the destination node is present, too. Thus it's possible to addEdge from an already added node to an unknown node.

      Whereas hasNode("B") will state that there is no node "B" in the Graph g, hasEdgde("A", "B") will return true which is at least misleading. I think it's inconsistent as I would expected this implies there is a node "B" also present in the Graph g.



      directed graph

      Since addEdge adds an edge from a source node to a destination node it's more precise to speak of a directed graph. Otherwise



      g.hasEdge("B", "A");


      needs to return true. But actually it isn't.



      readding a node is possbile

      Another point: It's possible to add already added nodes again.



      g.addNode("A");


      This results in replacing the current node by a new one. There is no exception and hasNode("A") will still return true. But all edges from the previous node to other nodes are lost.



      System.out.println(g.hasEdge("A", "B")); // false


      This should be prevented.



      readding an edge

      Readding an edge doesn't throw an exception. But it doesn't add an edge actually. It's impossible since a node is storing it's edges in a Set. A Set will not add an already present element once again. As long as there is no need to know how many times an edge from a node to another was add this isn't severe.



      Some further hints:




      • You can declare nodes as Map<String, Set<String>>. Since you're using interface methods only, there is no need to use the implementation types.

      • When adding a node calling first nodes.containsKey(name) and then on success calling nodes.put(name, new HashSet<String>()) has double complexity as the element within the map has to be looked up twice. But sinnce adding a node several times shouldn't be possible we can write


      instead:



      public void addNode(String name) {
      Set<String> node = nodes.get(name);
      if (node != null)
      throw new RuntimeException("addNode - node already exist");
      nodes.put(name, new HashSet<String>());
      }





      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        I think the code is incomplete. It's possible to build a Graph but there is no way to process it as there are no methods returning the state of a Graph.



        To be able to evaluate the shown code I'm going to extend it by two methods:



        /**
        * Returns true if a node with the given name was added.
        */
        public boolean hasNode(String name) {
        return nodes.containsKey(name);
        }


        /**
        * Returns true if an edge form source node to destination node (identified by their names) was added.
        */
        public boolean hasEdge(String src, String dest) {
        HashSet<String> adjList = nodes.get(src);
        return adjList != null && adjList.contains(dest);
        }


        Let's use a simple example to show some shortcomings:



        public static void main(String args) {
        Graph g = new Graph();
        g.addNode("A");
        g.addEdge("A", "B");

        System.out.println(g.hasNode("A")); // true
        System.out.println(g.hasNode("B")); // false
        System.out.println(g.hasEdge("A", "B")); // true
        }


        egdes to missing nodes

        The method addEdge verifies that a source node is already present. But it doensn't verify if the destination node is present, too. Thus it's possible to addEdge from an already added node to an unknown node.

        Whereas hasNode("B") will state that there is no node "B" in the Graph g, hasEdgde("A", "B") will return true which is at least misleading. I think it's inconsistent as I would expected this implies there is a node "B" also present in the Graph g.



        directed graph

        Since addEdge adds an edge from a source node to a destination node it's more precise to speak of a directed graph. Otherwise



        g.hasEdge("B", "A");


        needs to return true. But actually it isn't.



        readding a node is possbile

        Another point: It's possible to add already added nodes again.



        g.addNode("A");


        This results in replacing the current node by a new one. There is no exception and hasNode("A") will still return true. But all edges from the previous node to other nodes are lost.



        System.out.println(g.hasEdge("A", "B")); // false


        This should be prevented.



        readding an edge

        Readding an edge doesn't throw an exception. But it doesn't add an edge actually. It's impossible since a node is storing it's edges in a Set. A Set will not add an already present element once again. As long as there is no need to know how many times an edge from a node to another was add this isn't severe.



        Some further hints:




        • You can declare nodes as Map<String, Set<String>>. Since you're using interface methods only, there is no need to use the implementation types.

        • When adding a node calling first nodes.containsKey(name) and then on success calling nodes.put(name, new HashSet<String>()) has double complexity as the element within the map has to be looked up twice. But sinnce adding a node several times shouldn't be possible we can write


        instead:



        public void addNode(String name) {
        Set<String> node = nodes.get(name);
        if (node != null)
        throw new RuntimeException("addNode - node already exist");
        nodes.put(name, new HashSet<String>());
        }





        share|improve this answer












        I think the code is incomplete. It's possible to build a Graph but there is no way to process it as there are no methods returning the state of a Graph.



        To be able to evaluate the shown code I'm going to extend it by two methods:



        /**
        * Returns true if a node with the given name was added.
        */
        public boolean hasNode(String name) {
        return nodes.containsKey(name);
        }


        /**
        * Returns true if an edge form source node to destination node (identified by their names) was added.
        */
        public boolean hasEdge(String src, String dest) {
        HashSet<String> adjList = nodes.get(src);
        return adjList != null && adjList.contains(dest);
        }


        Let's use a simple example to show some shortcomings:



        public static void main(String args) {
        Graph g = new Graph();
        g.addNode("A");
        g.addEdge("A", "B");

        System.out.println(g.hasNode("A")); // true
        System.out.println(g.hasNode("B")); // false
        System.out.println(g.hasEdge("A", "B")); // true
        }


        egdes to missing nodes

        The method addEdge verifies that a source node is already present. But it doensn't verify if the destination node is present, too. Thus it's possible to addEdge from an already added node to an unknown node.

        Whereas hasNode("B") will state that there is no node "B" in the Graph g, hasEdgde("A", "B") will return true which is at least misleading. I think it's inconsistent as I would expected this implies there is a node "B" also present in the Graph g.



        directed graph

        Since addEdge adds an edge from a source node to a destination node it's more precise to speak of a directed graph. Otherwise



        g.hasEdge("B", "A");


        needs to return true. But actually it isn't.



        readding a node is possbile

        Another point: It's possible to add already added nodes again.



        g.addNode("A");


        This results in replacing the current node by a new one. There is no exception and hasNode("A") will still return true. But all edges from the previous node to other nodes are lost.



        System.out.println(g.hasEdge("A", "B")); // false


        This should be prevented.



        readding an edge

        Readding an edge doesn't throw an exception. But it doesn't add an edge actually. It's impossible since a node is storing it's edges in a Set. A Set will not add an already present element once again. As long as there is no need to know how many times an edge from a node to another was add this isn't severe.



        Some further hints:




        • You can declare nodes as Map<String, Set<String>>. Since you're using interface methods only, there is no need to use the implementation types.

        • When adding a node calling first nodes.containsKey(name) and then on success calling nodes.put(name, new HashSet<String>()) has double complexity as the element within the map has to be looked up twice. But sinnce adding a node several times shouldn't be possible we can write


        instead:



        public void addNode(String name) {
        Set<String> node = nodes.get(name);
        if (node != null)
        throw new RuntimeException("addNode - node already exist");
        nodes.put(name, new HashSet<String>());
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Aug 27 at 13:23









        LuCio

        1012




        1012






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f202540%2fadjacency-list-graph-in-java%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre