Does creating a custom graph data structure violate any principles?
I'm working on a small scientific course project related to circuit testing using continuous methods. The program would parse circuit definition files and then build an easily modifiable graph structure representing the circuit.Then certain modifications are done to that graph, and it is topologically sorted. After sorting, the graph is converted into a static structure that consists of a list of arrays, where every array corresponds to a certain topological sorting degree. After that, the circuit can be simulated easily as you 开发者_Python百科can rely on the sorting order and process the model sequentially.
Now that is all nice and logical, but the two graphs I mentioned are custom data structures, which:
1)Are not built quite to the STL specifications (would be long and difficult for me anyway - graphs are way more complex than vectors and lists)
2)For the second graph, I assume it's not modifiable and use a vector of vectors or a list of vectors for speed.
3)The set of operations available for my graphs is limited and reflects the needs of my project.
4)The code is simple.
Now I'm just a 3rd year IT student, and after having done a course in Software Design and after reading some real life code, I wonder:
1)Can (or even may) the code be as simple?
2)Don't I violate any of the thousands of principles of Software Design with making assumptions about the data structures?
3)Should I really always conform to STL specifications for all the data structures I create in this and future projects?
This project uses C++.
Thank you for your attention! I'd appreciate a fundamental and theoretical answer to these questions, as well as an example of practical approach to this problem.
1)Can (or even may) the code be as simple?
Not only can it be, it should be. There is no need for code to be complicated.
2)Don't I violate any of the thousands of principles of Software Design with making assumptions about the data structures?
Um, how can you do otherwise. This question doesn't make sense to me.
3)Should I really always conform to STL specifications for all the data structures I create in this and future projects?
Nope. For example, if you don't need to iterate a structure, don't provide iterators. Only implement what you actually need.
I would see nothing wrong with a simple design like this:
typedef int node_type; // or a more complex type here
typedef std::list<node_type> node_list;
typedef std::pair<node_list::const_iterator, node_list::const_iterator> edge_type;
typedef std::list<edge_type> edge_list;
struct graph
{
node_list nodes;
edge_list edges;
// Some member functions for doing specific things here
// for instance:
void remove_node(node_list::iterator i)
{
nodes.erase(i);
edges.remove_if(connects(i));
}
};
where
struct connects
{
connects(node_list::const_iterator i) : i(i) {}
bool operator()(const edge_type& e) const
{
return e.first == i || e.second == i;
}
private:
node_list::const_iterator i;
};
It stays simple, modular, and allows you to use the standard library on it. It allows you to iterate on nodes and edges. If you want the adjacency list of a vertex, you will have to loop over the whole edge list, but this is by design (you want a better structure if you want to do this fast).
For instance, define (this one is unfortunately not standard)
template <typename I, typename F, typename G>
F for_each_if(I first, I last, F f, G pred)
{
for ( ; first!=last; ++first ) if (pred(*first)) f(*first);
return f;
}
and now you can do
for_each_if(g.edges.begin(), g.edges.end(), something, connects(some_node));
to iterate over the adjacency list of some_node
.
With C++0x there are more elegant ways to code such algorithms (using lambdas).
精彩评论