Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programming a simple object oriented graph in C++

I am really trying to be a better programmer, and to make more modular, organized code.

As an exercise, I was trying to make a very simple Graph class in C++ with STL. In the code below, my Node object does not compile because the commented line results in a reference to a reference in STL.

#include <set>

class KeyComparable
{
public:
  int key;
};

bool operator <(const KeyComparable & lhs, const KeyComparable & rhs)
{
  return lhs.key < rhs.key;
}

class Node : public KeyComparable
{
public:
  // the following line prevents compilation
  // std::set<Node &> adjacent;
};

I would like to store the edges in a set (by key) because it allows fast removal of edges by key. If I were to store list<Node*>, that would work fine, but it wouldn't allow fast deletion by key.

If I use std::set<Node>, changes made through an edge will only change the local copy (not actually the adjacent Node). If I use std::set<Node*>, I don't believe the < operator will work because it will operate on the pointers themselves, and not the memory they index.

I considered wrapping references or pointers in another class, possibly my KeyComparable class (according to the linked page, this is how boost handles it).

Alternatively, I could store the std::list<Node*> and a std::map<int, iterator>' of locations in thestd::list`. I'm not sure if the iterators will stay valid as I change the list.

Ages ago, everything here would just be pointers and I'd handle all the data structures manually. But I'd really like to stop programming C-style in every language I use, and actually become a good programmer.

What do you think is the best way to handle this problem? Thanks a lot.

like image 475
user Avatar asked Mar 17 '12 16:03

user


People also ask

What is simple graph in DSA?

A simple graph, also called a strict graph (Tutte 1998, p. 2), is an unweighted, undirected graph containing no graph loops or multiple edges (Gibbons 1985, p.

How are graphs represented in C?

This C program generates graph using Adjacency Matrix Method. A graph G,consists of two sets V and E. V is a finite non-empty set of vertices. E is a set of pairs of vertices,these pairs are called as edges V(G) and E(G) will represent the sets of vertices and edges of graph G.


1 Answers

As you have deduced, you can't store references in STL containers because one of the requirements of items stored is that they be assignable. It's same reason why you can't store arrays in STL containers. You also can't overload operators without at least one being a user-defined type, which makes it appear that you can't do custom comparisons if you store pointers in an STL class...

However, you can still use std::set with pointers if you give set a custom comparer functor:

struct NodePtrCompare {
    bool operator()(const Node* left, const Node* right) const { 
        return left->key < right->key;
    }
};

std::set<Node*, NodePtrCompare> adjacent;

And you still get fast removals by key like you want.

like image 96
Seth Carnegie Avatar answered Sep 21 '22 05:09

Seth Carnegie