next up previous contents
Next: Run Time Results: Up: The Graph Class: Previous: The Gedge Class Implementation:

The Graph Class Implementation:

Next, we implement the Graph class itself. We begin with the grab and print methods and the overloaded input and output operators.

istream& operator>>(istream& in, Graph& A)
  {A.grab(in); return(in);}
istream& operator>>(istream& in, Graph* A)
  {A->grab(in); return(in);}
ostream& operator<<(ostream& out,const Graph& A)
  {A.print(out); return(out);}
ostream& operator<<(ostream& out,const Graph* A)
  {A->print(out); return(out);}
istream& Graph::grab(istream& input){}
ostream& Graph::print(ostream& output) const
{
  output << "Graph: " << endl;
  GnodePtrBagIter nit(nodes());
  if(nit){
    output << "Nodes: " << endl;
    }
  for( ; nit; ++nit){
    output << "  " << nit()->name();
    }
  const char *p = "  Edges:  ";
  const char *q = "          ";
  for(GedgePtrBagIter eit(edges());eit;++eit){
    output << endl << p << eit()->from()->name()
           << "-----(" << eit()->weight() << ")---> "
           << eit()->to()->name();
    p = q;
    }
  output << endl << "End Graph " << endl;
  return output;
}

Next, the constructor and destructor:

Graph::Graph(){}
Graph::~Graph()
{
  for(GedgePtrBagIter eit(d_edges); eit; ++eit){
    if(eit()!=NULL)
      delete eit();
    }
  for(GnodePtrBagIter nit(d_nodes); nit; ++nit){
    delete nit();
    }
}

Define the add, find and remove node methods:

 
Gnode* Graph::addNode(const char *nodeName)
{
  Gnode *p= new Gnode(nodeName);
  d_nodes.add(p);
  return p;
}
Gnode *Graph::findNode(const char *nodeName)
{
  for(GnodePtrBagIter it(d_nodes); it; ++it){
    if(0==strcmp(it()->name(),nodeName)){
      return it();
      }
    }
  return 0;
}

void Graph::removeNode(Gnode *node)
{
  GnodePtrBagManip nodeMan(&d_nodes);
  while(nodeMan){
    if(nodeMan()==node){
      for(GedgePtrBagIter it(nodeMan()->edges());it;++it){
        d_edges.removeAll(it());
        }
      nodeMan.remove();
      }
    else{
      nodeMan.advance(); 
      }        
    }//while loop 
}

Finally, define the add, find and remove edge methods:

Gedge *Graph::addEdge(Gnode* from,Gnode* to,double weight)
{
  Gedge *p = new Gedge(from,to,weight);
  d_edges.add(p);
  from->add(p);
  to->add(p);
  return p;
}
Gedge *Graph::findEdge(Gnode *from,Gnode *to)
{
  for(GedgePtrBagIter it(d_edges);it;++it){
    if((Gnode *)it()->from()==from && (Gnode *)it()->to()==to){
      return it();
      }
    }
   return 0;
}
void Graph::removeEdge(Gedge *edge)
{
  GedgePtrBagManip edgeMan(&d_edges);
  while(edgeMan){
    if(edgeMan()==edge){
      edge->to()->remove(edge);
      edge->from()->remove(edge);
      edgeMan.remove();
      }
    else{
      edgeMan.advance();
      }
    }
}

These methods return the bags of node pointers associated with the full graph or the bag of edge pointers for the graph.

const GnodePtrBag& Graph::nodes() const{return d_nodes;}
const GedgePtrBag& Graph::edges() const{return d_edges;}



Jim Peterson
1999-05-17