\$\begingroup\$
\$\endgroup\$
3
Please note the following:
- All edges are directed
- Removal of edges/nodges is not implemented yet
- A user of the class
Graph
can never (hopefully) access aNode
directly - If one tries to add an edge to a node that does not exist,
insert_edge()
will do nothing. - A
Vertex
cannot point to another vertex with several edges. - While the base class
Graph
works perfectly, I would like to create more advance graphs that could be used for maximum flow algorithm, weighted graphed etc. by creating new classes and inherit functions fromGraph
. But this seems impossible by the current implementation. It seems that the only way for a smooth solution for this right now is to add more data members toNode
(int weight
for example). Any idea on what I can do for making this possible with inheriting fromGraph
instead?
class Node
{
public:
std::string get_name()const;
//protected:
Node() = default;
Node( const std::string & n )
: name(n)
{}
std::vector<Node*> neighbours;
private:
std::string name;
};
class Graph : public Node
{
public:
void insert_node( std::string);
void insert_edge( std::string, std::string);
void print_node( const std::string) const;
void print_graph() const;
protected:
void insert_edge( Node*, Node*);
Node* get_node( std::string ) const;
bool is_node( Node * );
private:
std::vector<Node*> list;
};
std::string
Node::get_name() const
{
return name;
}
void
Graph::insert_node( std::string name)
{
for( auto& node : list )
{
if( name == node -> get_name() )
{
return;
}
}
Node *temp = new Node(name);
list.push_back ( temp );
}
void
Graph::insert_edge( Node *n, Node *new_edge )
{
if( n == nullptr || new_edge == nullptr )
{
return;
}
if( !is_node( n ) )
{
return;
}
for( auto& node : list )
{
if( n -> get_name() == node -> get_name() )
{
for( auto& current_edges : node -> neighbours )
{
if( current_edges -> get_name() == new_edge -> get_name() )
{
return;
}
}
node -> neighbours.push_back( new_edge );
}
}
}
void
Graph::insert_edge( std::string n, std::string new_edge)
{
Node* temp1 = get_node( n );
Node* temp2 = get_node( new_edge );
insert_edge( temp1, temp2 );
}
Node*
Graph::get_node( std::string name ) const
{
for( auto& node : list )
{
if( name == node -> get_name() )
{
return node;
}
}
return nullptr;
}
void
Graph::print_node( std::string name ) const
{
std::cout << name << " : ";
for( auto& node : list )
{
if(name == node -> get_name() )
{
for( auto& edge : node -> neighbours )
{
std::cout << " -> " << edge -> get_name();
}
std::cout << std::endl;
break;
}
}
}
void
Graph::print_graph() const
{
for( auto& node : list )
{
std::cout << node -> get_name() << " : ";
for( auto& edge : node -> neighbours )
{
std::cout << " -> " << edge -> get_name();
}
std::cout << std::endl;
}
}
bool
Graph::is_node( Node *n )
{
for( auto& node : list )
{
if( node -> get_name() == n -> get_name() )
{
return true;
}
}
return false;
}
asked Dec 27, 2014 at 21:17
-
\$\begingroup\$ Did you omit a level of indentation pretty much everywhere intentionally, or was that a problem when pasting the code here? \$\endgroup\$glampert– glampert2014年12月27日 21:25:58 +00:00Commented Dec 27, 2014 at 21:25
-
\$\begingroup\$ My code is indentended in my editor, but my I pasted it here, the site complaided that it was not four whitespace so I just hitted the spacebar so it was 4 whitespace in the code...Is there a better way? \$\endgroup\$Bojack– Bojack2014年12月27日 21:31:45 +00:00Commented Dec 27, 2014 at 21:31
-
\$\begingroup\$ Humm, not that I know of... Which editor are you using? On Vim and Emacs is pretty easy to replace tabs with spaces... \$\endgroup\$glampert– glampert2014年12月27日 22:05:16 +00:00Commented Dec 27, 2014 at 22:05
1 Answer 1
\$\begingroup\$
\$\endgroup\$
5
I don't like that std::vector<Node*> neighbours;
is a data member with public scope in Node
. I would suggest doing it private
and provide a getter for it, or provide a Node::push_back()
, etc.
As for you question of adding a data member weight in Graph
, I think that's not very nice, since - in my mind - weight is an attribute every node has, thus it should be a data member of Node
.
answered Dec 28, 2014 at 16:22
-
\$\begingroup\$ Neighbors should be protected so Graph can use it, but I have some compiling problems with that right now! I guess I am not clear enough with my description! I would like to great graphs with weights so I can implement dijkstra algorithm. I would also like to great graphs with capacity so I can implement different maximum flow algorithms as well. This makes it problematic to store both weights, capacity, etc. in node. \$\endgroup\$Bojack– Bojack2014年12月28日 17:11:36 +00:00Commented Dec 28, 2014 at 17:11
-
\$\begingroup\$ Therefore, I think it is better to create a class Graph_Weight that inherit from class Graph and give that Graph weight instead of the class Node and another class Graph_capacity that have capacity. I am clear with my thoughts? \$\endgroup\$Bojack– Bojack2014年12月28日 17:15:19 +00:00Commented Dec 28, 2014 at 17:15
-
\$\begingroup\$ @user1991779 I thought it was public, because you have commented protected! Maybe you could make an Edge class as well. However yes, your idea is nice too! :) Should I edit my answer or something or it is good as is? (because I saw that you didn't accept it). \$\endgroup\$gsamaras– gsamaras2014年12月28日 18:11:29 +00:00Commented Dec 28, 2014 at 18:11
-
\$\begingroup\$ I have made a lot of modifications, I will probably post it tomorrow. I would like to get some more comments on my choice of data structures! \$\endgroup\$Bojack– Bojack2015年01月07日 21:18:15 +00:00Commented Jan 7, 2015 at 21:18
-
\$\begingroup\$ Don't you think that the new ones should be a new question? Just an idea. I am not sure. :) @user1991779 \$\endgroup\$gsamaras– gsamaras2015年01月07日 21:34:08 +00:00Commented Jan 7, 2015 at 21:34
lang-cpp