# HG changeset patch # User alpar # Date 1070739147 0 # Node ID 207fb3c727cb0cb0a188b7e3f289ab1b80593aaa # Parent d10681d156f9ae83cf53b40e26595baa6d55b629 src/demo/graph.h: a proposal for a graph implementation src/demo/graphdemo.cc: a simle demo using graph.h diff -r d10681d156f9 -r 207fb3c727cb src/include/graph.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/include/graph.h Sat Dec 06 19:32:27 2003 +0000 @@ -0,0 +1,381 @@ +// -*-mode: c++; -*- +#ifndef __GRAPH_H_ +#define __GRAPH_H_ + +//inline void *operator new(size_t s, void *p) { return p; } +#include + +namespace NEGRO +{ + using namespace std; + +#include "oldgraph.h" + + template class Graph : protected OldGraph + { + public: + typedef E EdgeType; + typedef N NodeType; + + class EdgePoint + { + public: + NEGRO::EdgePoint e; + bool isValid() { return e; } + }; + + class InEdgePoint : public EdgePoint {}; + class OutEdgePoint : public EdgePoint {}; + class BiEdgePoint : public EdgePoint {}; + class SymEdgePoint : public EdgePoint {}; + + typedef int NodePoint; + + class NodeIterator; + + class EdgeIterator; + class InEdgeIterator; + class OutEdgeIterator; + class BiEdgeIterator; + class SymEdgeIterator; + class AllEdgeIterator; + + class FirstAnythingTypeNode; + + friend class NodeIterator; + friend class EdgeIterator; + friend class InEdgeIterator; + friend class OutEdgeIterator; + friend class BiEdgeIterator; + friend class SymEdgeIterator; + friend class AllEdgeIterator; + + class NodeIterator + { + Graph *G; //operator*() miatt kell!!! + int n; //nem kellene, ha itt mutato lenne!! + public: + + NodeIterator() {;} + NodeIterator(const NodeIterator &i) {G=i.G;n=i.n;} + + NodeIterator &GoNext() { n=G->NextNode(n); return *this;} + NodeIterator Next() const { return NodeIterator(*this).GoNext();} + NodeIterator &operator++() { return GoNext();} + NodeIterator operator++(int) + {NodeIterator tmp(*this); GoNext(); return tmp;} + bool isValid() { return n!=INVALID; } + + N &operator*() const { return G->Data(n); } + N *operator->() const { return &G->Data(n); } + + bool operator==(const NodeIterator &i) const {return n==i.n;} + bool operator!=(const NodeIterator &i) const {return n!=i.n;} + + friend class Graph; + friend class EdgeIterator; + friend class InEdgeIterator; + friend class OutEdgeIterator; + friend class BiEdgeIterator; + friend class SymEdgeIterator; + friend class AllEdgeIterator; + friend class FirstAnythingTypeNode; + + //Nem kellene egy: + // static NodeIterator &GetInvalid(); ? + }; + + class EdgeIterator + { + + Graph *G; //Itt baj van!!!!! operator*() miatt kell! + //Ez csak kicsit baj, de: + // Meg a From() es To() miatt!!!!!!!!!! + + NEGRO::EdgePoint e; + + public: + EdgeIterator() {;} //Kell inicializalni? (Nem) + EdgeIterator(const EdgeIterator &i) {G=i.G;e=i.e;} + + // Lehet, hogy ez a ketto nem kell!!! + + NodeIterator From() const {NodeIterator i;i.G=G;i.n=e->From();return i;} + NodeIterator To() const {NodeIterator i;i.G=G;i.n=e->To();return i;} + + bool isValid() {return e;} + E &operator*() const { return G->Data(e); } + E *operator->() const { return &G->Data(e); } + + //operator const OutEdgeIterator (); + //operator const InEdgeIterator (); + //operator const BiEdgeIterator (); + //operator const SymEdgeIterator(); //Ez kerdeses, mit csinal + + bool operator==(const EdgeIterator &i) const {return e==i.e;} + bool operator!=(const EdgeIterator &i) const {return e!=i.e;} + + friend class Graph; + friend class InEdgeIterator; + friend class OutEdgeIterator; + friend class BiEdgeIterator; + friend class SymEdgeIterator; + friend class AllEdgeIterator; + }; + + class BiEdgeIterator : public EdgeIterator + { + public: + BiEdgeIterator &GoNextIn() { e=e->NextIn(); return *this;} + BiEdgeIterator &GoNextOut() { e=e->NextOut(); return *this;} + BiEdgeIterator NextIn() const {return BiEdgeIterator(*this).GoNextIn();} + BiEdgeIterator NextOut() const {return BiEdgeIterator(*this).GoNextOut();} + + operator InEdgeIterator () + {InEdgeIterator i; i.G=G;i.e=e;return i;} + operator OutEdgeIterator () + {OutEdgeIterator i; i.G=G;i.e=e;return i;} + //operator const SymEdgeIterator () + + friend class Graph; + }; + + class InEdgeIterator : public EdgeIterator + //Ne a BiEdgeIterator-bol szarmazzon? + { + public: + InEdgeIterator &GoNext() { e=e->NextIn(); return *this;} + InEdgeIterator Next() const {return InEdgeIterator(*this).GoNext();} + InEdgeIterator &operator++() { return GoNext();} + InEdgeIterator operator++(int) + {InEdgeIterator tmp(*this); GoNext(); return tmp;} + + operator const OutEdgeIterator () + {OutEdgeIterator i; i.G=G;i.e=e;return i;} + operator const BiEdgeIterator () + {EdgeIterator i; i.G=G;i.e=e;return i;} + // operator const SymEdgeIterator (); + + NodeIterator Anode() const {return To();} + NodeIterator Bnode() const {return From();} + + friend class Graph; + }; + + class OutEdgeIterator : public EdgeIterator + { + public: + OutEdgeIterator &GoNext() { e=e->NextOut(); return *this;} + OutEdgeIterator Next() const {return OutEdgeIterator(*this).GoNext();} + OutEdgeIterator &operator++() { return GoNext();} + OutEdgeIterator operator++(int) + {OutEdgeIterator tmp(*this); GoNext(); return tmp;} + + NodeIterator Anode() const {return From();} + NodeIterator Bnode() const {return To();} + + operator const InEdgeIterator () + {InEdgeIterator i; i.G=G;i.e=e;return i;} + operator const BiEdgeIterator () + {BiEdgeIterator i; i.G=G;i.e=e;return i;} + //operator const SymEdgeIterator(); + + friend class Graph; + }; + + class SymEdgeIterator : public EdgeIterator + { + NodeIterator n; // Itt ketszer van a G + + public: + SymEdgeIterator &GoNext() { e=e->NextEdge(n.n); return *this;} + SymEdgeIterator Next() const {return SymEdgeIterator(*this).GoNext();} + SymEdgeIterator &operator++() { return GoNext();} + SymEdgeIterator operator++(int) + {SymEdgeIterator tmp(*this); GoNext(); return tmp;} + + NodeIterator Anode() const {return n;} + NodeIterator Bnode() const {return n.n==From().n?To():From();} + + operator const InEdgeIterator () + {InEdgeIterator i; i.G=G;i.e=e;return i;} + operator const OutEdgeIterator () + {OutEdgeIterator i; i.G=G;i.e=e;return i;} + operator const BiEdgeIterator () + {BiEdgeIterator i; i.G=G;i.e=e;return i;} + + friend class Graph; + }; + + class AllEdgeIterator : public EdgeIterator + { + NodeIterator n; // Itt ketszer van a G + + public: + AllEdgeIterator &GoNext() + { + e=e->NextOut(); + if(!e && (++n).isValid()) e=G->OldGraph::FirstOut(n.n); + return *this; + } + AllEdgeIterator Next() const {return AllEdgeIterator(*this).GoNext();} + AllEdgeIterator &operator++() { return GoNext();} + AllEdgeIterator operator++(int) + {AllEdgeIterator tmp(*this); GoNext(); return tmp;} + + + NodeIterator Anode() const {return n;} + NodeIterator Bnode() const {return n.n==From().n?To():From();} + + operator const InEdgeIterator () + {InEdgeIterator i; i.G=G;i.e=e;return i;} + operator const OutEdgeIterator () + {OutEdgeIterator i; i.G=G;i.e=e;return i;} + operator const BiEdgeIterator () + {BiEdgeIterator i; i.G=G;i.e=e;return i;} + + friend class Graph; + }; + + typedef NodeIterator DeletingNodeIterator; + typedef EdgeIterator DeletingEdgeIterator; + typedef BiEdgeIterator DeletingBiEdgeIterator; + typedef OutEdgeIterator DeletingOutEdgeIterator; + typedef InEdgeIterator DeletingInEdgeIterator; + typedef SymEdgeIterator DeletingSymEdgeIterator; + + const NodeIterator &FirstNode() + { + NodeIterator i; + i.G=this;i.n=OldGraph::FirstNode(); + return i; + } + + void GetFirst(NodePoint &p) { p=OldGraph::FirstNode(); } + + void GetFirst(InEdgePoint &p,const NodePoint &n) + { p=OldGraph::FirstIn(n); } + void GetFirst(OutEdgePoint &p,const NodePoint &n) + { p=OldGraph::FirstOut(n); } + void GetFirst(SymEdgePoint &p,const NodePoint &n) + { p=OldGraph::FirstEdge(n); } + void GetFirst(EdgePoint &p) //Vegigmegy mindenen + { p.e=NodeNum()?OldGraph::FirstOut(OldGraph::FirstNode()):NULL;} + + void GetFirst(NodeIterator &i) { i.G=this;i.n=OldGraph::FirstNode();} + + void GetFirst(InEdgeIterator &i,const NodeIterator &n) + { i.G=this;i.e=OldGraph::FirstIn(n.n); } + void GetFirst(OutEdgeIterator &i,const NodeIterator &n) + { i.G=this;i.e=OldGraph::FirstOut(n.n); } + void GetFirst(SymEdgeIterator &i,const NodeIterator &n) + { i.G=this;i.e=OldGraph::FirstSym(n.n); } + void GetFirst(AllEdgeIterator &i) //Vegigmegy mindenen + { + i.G=this; + GetFirst(i.n); + i.e=OldGraph::NodeNum()?OldGraph::FirstOut(i.n.n):NULL; + } + + + + //Vagy beginnode()? + const DeletingEdgeIterator &FirstOut(const NodeIterator &n) + { + EdgeIterator i; + i.G=n.G;i.edge=n.G->OldGraph::FirstOut(n.n); + return i; + } + const DeletingEdgeIterator &FirstIn(const NodeIterator &n) + { + EdgeIterator i; + i.G=n.G;i.edge=n.G->OldGraph::FirstIn(n.n); + return i; + } + const DeletingSymEdgeIterator &FirstSym(const NodeIterator &n) + { + EdgeIterator i; + i.G=n.G;i.n=n.n; + i.edge=n.G->OldGraph::FirstEdge(n.n); + return i; + } + + // class FirstAnythingType; + // friend class FirstAnythingType; + + class FirstAnythingTypeNode + { + NodeIterator n; + public: + FirstAnythingTypeNode(NodeIterator i) : n(i) {} + + operator const InEdgeIterator () const + {InEdgeIterator i; n.G->GetFirst(i,n);return i;} + operator const OutEdgeIterator () const + {OutEdgeIterator i; n.G->GetFirst(i,n);return i;} + operator const SymEdgeIterator () const + {SymEdgeIterator i; n.G->GetFirst(i,n);return i;} + + operator const InEdgePoint () const + {InEdgePoint i; n.G->GetFirst(i,n);return i;} + operator const OutEdgePoint () const + {OutEdgePoint i; n.G->GetFirst(i,n);return i;} + operator const SymEdgePoint () const + {SymEdgePoint i; n.G->GetFirst(i,n);return i;} + }; + + class FirstAnythingType + { + Graph *G; + public: + FirstAnythingType(Graph *gg) : G(gg) {} + + operator const AllEdgeIterator () const + {AllEdgeIterator i; G->GetFirst(i);return i;} + operator const EdgePoint () const + {EdgePoint i; G->GetFirst(i);return i;} + operator const NodeIterator () const + {NodeIterator i; G->GetFirst(i);return i;} + operator const NodePoint () const + {NodePoint i; G->GetFirst(i);return i;} + } _FST; + + // const NodeIterator First() {NodeIterator i;GetFirst(i); return i;} + FirstAnythingTypeNode First(NodeIterator &i) + {FirstAnythingTypeNode t(i); return t;} + const FirstAnythingType &First() {return _FST;} + + // LastNode() vagy endnode() stb. Nem kell? + + DeletingNodeIterator AddNode() + { + DeletingNodeIterator i; + i.G=this; i.n=OldGraph::AddNode(); + return i; + } + DeletingEdgeIterator + AddEdge(const NodeIterator from,const NodeIterator to) + { + DeletingEdgeIterator i; + i.G=this;i.e=OldGraph::AddEdge(from.n,to.n);return i; + } + + void Delete(DeletingNodeIterator n) {n.G->OldGraph::Delete(n.n);} + void Delete(DeletingEdgeIterator e) {e.G->OldGraph::Delete(e.e);} + + int NodeNum() { OldGraph::NodeNum(); } + int Clean() { OldGraph::Clean(); } + + Graph() : _FST(this) {} + }; + + /* Ez itt a fiam kommentje: + + +//#include + +#define INVALID -1 +#define FREE_NODE INVALID + +#define EDGE_BLOCK_SIZE 100 +#define INIT_NODES_SIZE 10 +#define INIT_EDGES_BLOCK_MAX 10 + +#define foreachNode(n,G) for((n)=(G).FirstNode();(n)!=INVALID;(n)=(G).NextNode(n)) +#define foreachIn(e,G,n) for((e)=(G).FirstIn(n) ;(e);(e)=(G).NextIn(e) ) +#define foreachOut(e,G,n) for((e)=(G).FirstOut(n);(e);(e)=(G).NextOut(e)) +#define foreachEdge(e,G,n) for((e)=(G).FirstEdge(n);(e);(e)=(G).NextEdge((n),(e))) + +struct EdgeIndex { int block,index; }; + +extern EdgeIndex InvalidIndex; + +class EdgeCorp; +typedef EdgeCorp *EdgePoint; + +class EdgeCorp { + public: + int from,to; //from==INVALID <=> this is a free edge. + EdgePoint previn,nextin,prevout,nextout; + EdgeIndex index; + + int From() { return from; } + int To() { return to; } + EdgePoint NextIn() { return nextin; } + EdgePoint NextOut() { return nextout; } +}; + +inline int From(EdgePoint e) { return e->from; } +inline int To(EdgePoint e) { return e->to; } +inline EdgePoint NextIn(EdgePoint e) { return e->nextin; } +inline EdgePoint NextOut(EdgePoint e) { return e->nextout; } + + +////////////////////////////////////////////////////////////////////// +// OLDGRAPH TEMPLATE +////////////////////////////////////////////////////////////////////// +// Copy Constructor should be provided for N + +//class Graph; +//class Graph::NodeIterator; //Nem megy. Disznosag! +template class OldGraph +{ + + // friend class NEGRO::Graph::NodeIterator; //Nem megy. Disznosag! + + + class nodes_t; + friend class OldGraph::nodes_t; + class edge_block; + friend class OldGraph::edge_block; + + class edge_t : public EdgeCorp { + public: + //edge_t *previn,*nextin,*prevout,*nextout; + union { + int _align; + char data[sizeof(E)]; + }; + }; + + class nodes_t { + public: + union { + int _align; + char data[sizeof(N)]; + }; + int indeg,outdeg; // indeg==FREE_NODE <=> this node is free. + EdgePoint firstin, firstout; + int prev,next; + + void Copy(nodes_t &n) + { + indeg = n.indeg; outdeg = n.outdeg; + firstin = n.firstin; firstout = n.firstout; + prev = n.prev; next = n.next; + if(n.indeg!=FREE_NODE) new(data) N(*(N*)(n.data)); + // if(n.indeg!=FREE_NODE) { + // new(data) N; + // (*(N*)(data))=(*(N*)(n.data)); + // } + } + + } *nodes; + int nodenum, nodes_size; + int firstnode, freenodes; + class edge_block { + public: + //edge_block *next; + // char fields[sizeof(edge_t)*EDGE_BLOCK_SIZE]; + edge_t fields[EDGE_BLOCK_SIZE]; + } **edges; + int edge_block_num,edge_block_max; + EdgePoint freeedges; + + void setup(int nosi = INIT_NODES_SIZE); + void destroy(); + void inc_nodes_size(int n); + + public: + int NodeNum() {return nodenum;}; + int EdgeNum(); + int MaxNode() {return nodes_size;}; + int FirstNode() {return firstnode;}; + int NextNode(int n) {return nodes[n].next;}; + int PrevNode(int n) {return nodes[n].prev;}; + N& operator()(int n) {return *(N*)(nodes[n].data);}; + N& Data (int n) {return *(N*)(nodes[n].data);}; + int AddNode(); + void AddNodeBlock(int n) {for(int i=0;i=0&&ndata);}; + E& Data (EdgePoint e) {return *(E*)(((edge_t*)e)->data);}; + int From(EdgePoint e) {return e->from;}; + int To(EdgePoint e) {return e->to;}; + EdgePoint NextIn(EdgePoint e) + {return e->nextin;}; + EdgePoint NextOut(EdgePoint e) + {return e->nextout;}; + EdgePoint AddEdge(int f, int t); + void Delete(EdgePoint e); + EdgePoint Edge(int f,int t); + // EdgePoint Edge(E &d) + // {return (EdgePoint)(((char*)&d)-(char*)&(((edge_t*)NULL)->data));}; + E& operator()(int f, int t) {return *(E*)(((edge_t*)Edge(f,t))->data);}; + E& Data(int f, int t) {return *(E*)(((edge_t*)Edge(f,t))->data);}; + void Delete(int f, int t) {Delete(Edge(f,t));}; + void Reverse(EdgePoint e); + + // Functions for EdgeIndex + + EdgePoint Edge(EdgeIndex i) + { return (EdgePoint)(edges[i.block]->fields+i.index);}; + EdgeIndex Index(EdgePoint e) { return e->index;}; + EdgeIndex Index(int f, int t) { EdgePoint e; return Edge(f,t)->index; } + void Delete(EdgeIndex i) { Delete(Edge(i));}; + E& operator()(EdgeIndex i) + {return *(E*)(edges[i.block]->fields[i.index].data);}; + E& Data(EdgeIndex i) + {return *(E*)(edges[i.block]->fields[i.index].data);}; + EdgePoint AddEdge(int f, int t,EdgeIndex in); + + + + // Operators for symmetric graphs: + + EdgePoint FirstEdge(int n) + { return (EdgePoint)(FirstIn(n)?FirstIn(n):FirstOut(n));}; + EdgePoint NextEdge(int n,EdgePoint e) + { return From(e)==n?NextOut(e):(NextIn(e)?NextIn(e):FirstOut(n)); }; + int Opposite(EdgePoint e,int n) + { return From(e)+To(e)-n; }; + + // Initializers, destructors + + OldGraph() {setup();}; + OldGraph(int nosi) {setup(nosi);}; + OldGraph(OldGraph &H) {setup();operator=(H);}; + ~OldGraph() {destroy();}; + void Clean(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);}; + void Clear(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);}; + + void DeleteEdges(); + + OldGraph &operator=(OldGraph &H); +}; + +////////////////////////////////////////////////////////////////////// +// Template Definitions +////////////////////////////////////////////////////////////////////// + +//#include + +//********************************************************************** +// OldGraph definitions +//********************************************************************** + +template void OldGraph::setup(int nosi) { + int i; + + //Set up nodes + nodenum = 0; + nodes_size = nosi; + // nodes = (nodes_t*) new char[sizeof(nodes_t)*nodes_size]; + nodes = (nodes_t*) new nodes_t [nodes_size]; + for(i=0;i void OldGraph::destroy() +{ + edge_block *oe; + int i; + + while(firstnode!=INVALID) Delete(firstnode); + delete [] nodes; + for(i=0;i void OldGraph::inc_nodes_size(int n) +{ + int i; + if(n<=nodenum) return; + + nodes_t *nn; +// nn = (nodes_t*) new char [sizeof(nodes_t)*n]; + nn = (nodes_t*) new nodes_t [n]; + for(i=0;i~N(); + } + + delete [] nodes; + nodes = nn; + for(i=nodes_size;i OldGraph &OldGraph::operator=(OldGraph &H) +{ + Clean(); + + int i; + EdgePoint e; + + for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i)) + { + AddNode(i); + operator()(i)=H(i); + } + for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i)) + for(e=H.FirstOut(i);e;e=H.NextOut(e)) + operator()(AddEdge(i,H.To(e),H.Index(e)))=H(e); + + return *this; +} + +template int OldGraph::EdgeNum() +{ + int n=firstnode, m=0; + EdgePoint e; + while(n != INVALID) + { + e=FirstOut(n); + while (e != NULL) + { + m++; + e=NextOut(e); + } + n=nodes[n].next; + } + return m; +} + +template int OldGraph::AddNode() +{ + int i; + + if(freenodes==INVALID) inc_nodes_size(2*nodes_size); + + i=freenodes; + if(firstnode!=INVALID) nodes[firstnode].prev=i; + freenodes=nodes[i].next; + new(nodes[i].data) N; //Explicit constructor call + nodes[i].next=firstnode; + nodes[i].prev=INVALID; + nodes[i].indeg=0; + firstnode=i; + if(freenodes!=INVALID) nodes[freenodes].prev=INVALID; + nodenum++; + return i; +} + +template int OldGraph::AddNode(int n) +{ + int i; + + if(n>=nodes_size) + { + for(i=INIT_NODES_SIZE;i<=n;i*=2) ; + inc_nodes_size(i); + } + + if(nodes[n].indeg==FREE_NODE) + { + new(nodes[n].data) N; //Explicit constructor call + if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev = nodes[n].prev; + if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next = nodes[n].next; + else freenodes = nodes[n].next; + + nodes[n].prev = INVALID; + if((nodes[n].next = firstnode)!=INVALID) nodes[firstnode].prev=n; + firstnode = n; + nodenum++; + nodes[n].indeg=0; + } + return n; +} + +template void OldGraph::Delete(int n) +{ + if(n==INVALID||nodes[n].indeg==FREE_NODE) return; + + EdgePoint e; + + while(e=FirstIn(n)) Delete(e); + while(e=FirstOut(n)) Delete(e); + + if(n==firstnode) firstnode=nodes[n].next; + if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next=nodes[n].next; + if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev=nodes[n].prev; + if(freenodes!=INVALID) nodes[freenodes].prev=n; + nodes[n].next=freenodes; + nodes[n].prev=INVALID; + nodes[n].indeg=FREE_NODE; + ((N*)(nodes[n].data))->~N(); //Explicit destructor call + freenodes=n; + + nodenum--; +} + +template EdgePoint OldGraph::AddEdge(int f, int t) +{ + int i; + edge_block *peb; + edge_block **ppeb; + edge_t *e; + + if(!freeedges) + { + if(edge_block_num>=edge_block_max) + { + ppeb = new edge_block* [edge_block_max*=2]; + for(i=0;ifields)[i].nextin=((edge_t*)peb->fields)+(i+1); + ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1); + ((edge_t*)peb->fields)[i].index.block = edge_block_num; + ((edge_t*)peb->fields)[i].index.index = i; + ((edge_t*)peb->fields)[i].from = INVALID; + } + ((edge_t*)peb->fields)[0].previn= + ((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=NULL; + freeedges = (edge_t*)peb->fields; + edge_block_num++; + } + + e=(edge_t *)freeedges; + new (e->data) E; //Explicit constructor call + freeedges=e->nextin; + if(freeedges) freeedges->previn=NULL; + + e->from=f; e->to=t; + e->previn=e->prevout=NULL; + e->nextin=nodes[t].firstin; + e->nextout=nodes[f].firstout; + if(nodes[t].firstin) nodes[t].firstin->previn=e; + if(nodes[f].firstout) nodes[f].firstout->prevout=e; + nodes[t].firstin=nodes[f].firstout=e; + nodes[t].indeg++; nodes[f].outdeg++; + + return (EdgePoint)e; + +} + +template +EdgePoint OldGraph::AddEdge(int f, int t, EdgeIndex in) +{ + int i; + edge_block *peb; + edge_block **ppeb; + edge_t *e; + + while(edge_block_num<=in.block) + { + if(edge_block_num>=edge_block_max) + { + ppeb = new edge_block* [edge_block_max*=2]; + for(i=0;ifields)[i].nextin=((edge_t*)peb->fields)+(i+1); + ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1); + ((edge_t*)peb->fields)[i].index.block = edge_block_num; + ((edge_t*)peb->fields)[i].index.index = i; + ((edge_t*)peb->fields)[i].from = INVALID; + } + ((edge_t*)peb->fields)[0].previn=NULL; + ((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=freeedges; + if(freeedges) + freeedges->previn = ((edge_t*)peb->fields) + (EDGE_BLOCK_SIZE-1); + freeedges = (edge_t*)peb->fields; + edge_block_num++; + } + + + e=((edge_t*)(edges[in.block]->fields))+in.index; + if(e->from==INVALID) + { + if(e->previn) e->previn->nextin = e->nextin; + else freeedges = e->nextin; + if(e->nextin) e->nextin->previn = e->previn; + + new (e->data) E; //Explicit constructor call + + e->from=f; e->to=t; + e->previn=e->prevout=NULL; + e->nextin=nodes[t].firstin; + e->nextout=nodes[f].firstout; + if(nodes[t].firstin) nodes[t].firstin->previn=e; + if(nodes[f].firstout) nodes[f].firstout->prevout=e; + nodes[t].firstin=nodes[f].firstout=e; + nodes[t].indeg++; nodes[f].outdeg++; + } + return (EdgePoint)e; +} + +template void OldGraph::Delete(EdgePoint e) +{ + if(!e||e->from==INVALID) return; + + ((E*)(((edge_t*)e)->data))->~E(); //Explicit destructor call + + nodes[e->from].outdeg--; nodes[e->to].indeg--; + + + if(e->previn) + e->previn->nextin=e->nextin; + else nodes[e->to].firstin=e->nextin; + if(e->prevout) + e->prevout->nextout=e->nextout; + else nodes[e->from].firstout=e->nextout; + if(e->nextin) + e->nextin->previn=e->previn; + if(e->nextout) + e->nextout->prevout=e->prevout; + + if(freeedges) freeedges->previn=e; + e->previn=NULL; e->nextin=freeedges; + + e->from = INVALID; + freeedges=e; +} + +template EdgePoint OldGraph::Edge(int f, int t) +{ + EdgePoint e; + + for(e=nodes[f].firstout;e&&e->to!=t;e=e->nextout) ; + + return (EdgePoint) e; +} + +template void OldGraph::Reverse(EdgePoint e) +{ + if(!e) return; + + nodes[e->from].outdeg--; nodes[e->to].indeg--; + + if(e->previn) + e->previn->nextin=e->nextin; + else nodes[e->to].firstin=e->nextin; + if(e->prevout) + e->prevout->nextout=e->nextout; + else nodes[e->from].firstout=e->nextout; + if(e->nextin) + e->nextin->previn=e->previn; + if(e->nextout) + e->nextout->prevout=e->prevout; + + int t,f; + f=e->to;e->to=t=e->from; + e->from=f; + + e->previn=e->prevout=NULL; + e->nextin=nodes[t].firstin; + e->nextout=nodes[f].firstout; + if(nodes[t].firstin) nodes[t].firstin->previn=e; + if(nodes[f].firstout) nodes[f].firstout->prevout=e; + nodes[t].firstin=nodes[f].firstout=e; + nodes[t].indeg++; nodes[f].outdeg++; + +} + +template void OldGraph::DeleteEdges() +{ + int n; + for(n=FirstNode();n!=INVALID;n=NextNode(n)) + while(FirstOut(n)) Delete(FirstOut(n)); +} + +#endif diff -r d10681d156f9 -r 207fb3c727cb src/work/graphdemo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/graphdemo.cc Sat Dec 06 19:32:27 2003 +0000 @@ -0,0 +1,98 @@ +#include +#include + +using namespace NEGRO; +using namespace std; + +class NodeData; +class EdgeData; + +typedef Graph TestGraph; + +class NodeData +{ +public: + int id; + bool isVis; +}; + +class EdgeData +{ +public: + int id; +}; + + +typedef Graph TestGraph; + +void main() +{ + TestGraph G; + TestGraph::NodeIterator n,m,o,p,q; + TestGraph::OutEdgeIterator e,f,g,h; + int i,j,k; + + + //for(i=1;i<=10;i++) G.AddNode().n=i; //Ez nagyon rossz!!!!!!!! + for(i=1;i<=10;i++) G.AddNode()->id=i; //Ez a jo!!!!!!!! + + //n=G.AddNode(); + + //for(i=1;i<=10;i++) cout << (G.AddNode()->n=i) << ' '; + //cout << '\n'; + + i=0; + for(G.GetFirst(n);n.isValid();n++) + for(G.GetFirst(m);m.isValid();++m) + if(n!=m) G.AddEdge(n,m)->id=++i; + + cout << "Number of edges: " << i << "\n\n"; + + TestGraph::AllEdgeIterator a; + for(G.GetFirst(a);a.isValid();++a) + cout << a->id << ":" << a.From()->id << "->" << a.To()->id << " "; + + cout << "\n\n\n"; + + for(G.GetFirst(n);n.isValid();++n) + { + cout << n->id << "->"; + for(G.GetFirst(e,n);e.isValid();++e) + cout << e->id << ":" << e.To()->id << ' '; + cout << '\n'; + } + + cout << "\n\n\n\nB-verzio:\n\n\n"; + + G.Clean(); + + for(i=1;i<=10;i++) G.AddNode()->id=i; + + i=0; + for(n=G.First();n.isValid();n++) + for(m=G.First();m.isValid();++m) + if(n!=m) G.AddEdge(n,m)->id=++i; + + ; + for(n=G.First();n.isValid();++n) + { + e=G.First(n); + while(e.isValid()) + if((e->id)%2) G.Delete(e++); + else ++e; + } + + for(a=G.First();a.isValid();++a) + cout << a->id << ": " << a.From()->id << "->" << a.To()->id << " "; + + cout << "\n\n\n"; + + for(n=G.First();n.isValid();++n) + { + cout << n->id << "->"; + for(e=G.First(n);e.isValid();++e) + cout << e->id << ":" << e.To()->id << ' '; + cout << '\n'; + } + +} diff -r d10681d156f9 -r 207fb3c727cb src/work/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/makefile Sat Dec 06 19:32:27 2003 +0000 @@ -0,0 +1,3 @@ +graphdemo: graphdemo.cc ../include/graph.h \ + ../include/oldgraph.h makefile + g++ -g -I../include -o graphdemo graphdemo.cc