src/include/oldgraph.h
author marci
Fri, 06 Feb 2004 11:45:47 +0000
changeset 67 5f86199dcf3e
parent 1 207fb3c727cb
permissions -rw-r--r--
.
alpar@1
     1
// -*-mode: c++; -*-
alpar@1
     2
#ifndef __OLDGRAPH_H_
alpar@1
     3
#define __OLDGRAPH_H_
alpar@1
     4
alpar@1
     5
#include <stdio.h>
alpar@1
     6
alpar@1
     7
//#include <new>
alpar@1
     8
alpar@1
     9
#define INVALID -1
alpar@1
    10
#define FREE_NODE INVALID
alpar@1
    11
alpar@1
    12
#define EDGE_BLOCK_SIZE 100
alpar@1
    13
#define INIT_NODES_SIZE 10
alpar@1
    14
#define INIT_EDGES_BLOCK_MAX 10
alpar@1
    15
alpar@1
    16
#define foreachNode(n,G) for((n)=(G).FirstNode();(n)!=INVALID;(n)=(G).NextNode(n))
alpar@1
    17
#define foreachIn(e,G,n)  for((e)=(G).FirstIn(n) ;(e);(e)=(G).NextIn(e) )
alpar@1
    18
#define foreachOut(e,G,n) for((e)=(G).FirstOut(n);(e);(e)=(G).NextOut(e))
alpar@1
    19
#define foreachEdge(e,G,n) for((e)=(G).FirstEdge(n);(e);(e)=(G).NextEdge((n),(e)))
alpar@1
    20
alpar@1
    21
struct EdgeIndex { int block,index; };
alpar@1
    22
alpar@1
    23
extern EdgeIndex InvalidIndex;
alpar@1
    24
alpar@1
    25
class EdgeCorp;
alpar@1
    26
typedef EdgeCorp *EdgePoint;
alpar@1
    27
alpar@1
    28
class EdgeCorp {
alpar@1
    29
 public:
alpar@1
    30
  int from,to;      //from==INVALID <=> this is a free edge.
alpar@1
    31
  EdgePoint previn,nextin,prevout,nextout;
alpar@1
    32
  EdgeIndex index;
alpar@1
    33
alpar@1
    34
  int From() { return from; }
alpar@1
    35
  int To() { return to; }
alpar@1
    36
  EdgePoint NextIn() { return nextin; }
alpar@1
    37
  EdgePoint NextOut() { return nextout; }
alpar@1
    38
};
alpar@1
    39
alpar@1
    40
inline int From(EdgePoint e) { return e->from; }
alpar@1
    41
inline int To(EdgePoint e) { return e->to; }
alpar@1
    42
inline EdgePoint NextIn(EdgePoint e) { return e->nextin; }
alpar@1
    43
inline EdgePoint NextOut(EdgePoint e) { return e->nextout; }
alpar@1
    44
alpar@1
    45
alpar@1
    46
//////////////////////////////////////////////////////////////////////
alpar@1
    47
//   OLDGRAPH TEMPLATE
alpar@1
    48
//////////////////////////////////////////////////////////////////////
alpar@1
    49
// Copy Constructor should be provided for N
alpar@1
    50
alpar@1
    51
//class Graph;
alpar@1
    52
//class Graph::NodeIterator; //Nem megy. Disznosag!
alpar@1
    53
template <class N, class E> class OldGraph
alpar@1
    54
{
alpar@1
    55
alpar@1
    56
  //  friend class NEGRO::Graph::NodeIterator; //Nem megy. Disznosag!
alpar@1
    57
alpar@1
    58
alpar@1
    59
  class nodes_t;
alpar@1
    60
  friend class OldGraph::nodes_t;
alpar@1
    61
  class edge_block;
alpar@1
    62
  friend class OldGraph::edge_block;
alpar@1
    63
  
alpar@1
    64
  class edge_t : public EdgeCorp {
alpar@1
    65
  public:
alpar@1
    66
    //edge_t *previn,*nextin,*prevout,*nextout;
alpar@1
    67
    union {
alpar@1
    68
      int _align;
alpar@1
    69
      char data[sizeof(E)];
alpar@1
    70
    };
alpar@1
    71
  };
alpar@1
    72
alpar@1
    73
  class nodes_t {
alpar@1
    74
  public:
alpar@1
    75
    union {
alpar@1
    76
      int _align;
alpar@1
    77
      char data[sizeof(N)];
alpar@1
    78
    };
alpar@1
    79
    int indeg,outdeg;           // indeg==FREE_NODE <=> this node is free.
alpar@1
    80
    EdgePoint firstin, firstout;
alpar@1
    81
    int prev,next;
alpar@1
    82
alpar@1
    83
    void Copy(nodes_t &n) 
alpar@1
    84
    {
alpar@1
    85
      indeg = n.indeg; outdeg = n.outdeg;
alpar@1
    86
      firstin = n.firstin; firstout = n.firstout;
alpar@1
    87
      prev = n.prev; next = n.next;
alpar@1
    88
      if(n.indeg!=FREE_NODE) new(data) N(*(N*)(n.data));
alpar@1
    89
      //      if(n.indeg!=FREE_NODE) {
alpar@1
    90
      //	new(data) N;
alpar@1
    91
      //	(*(N*)(data))=(*(N*)(n.data));
alpar@1
    92
      //      }
alpar@1
    93
    }
alpar@1
    94
    
alpar@1
    95
  } *nodes;
alpar@1
    96
  int nodenum, nodes_size;
alpar@1
    97
  int firstnode, freenodes;
alpar@1
    98
  class edge_block {
alpar@1
    99
  public:
alpar@1
   100
    //edge_block *next;
alpar@1
   101
    //    char fields[sizeof(edge_t)*EDGE_BLOCK_SIZE];
alpar@1
   102
    edge_t fields[EDGE_BLOCK_SIZE];    
alpar@1
   103
  } **edges;
alpar@1
   104
  int edge_block_num,edge_block_max;
alpar@1
   105
  EdgePoint freeedges;
alpar@1
   106
alpar@1
   107
  void setup(int nosi = INIT_NODES_SIZE);
alpar@1
   108
  void destroy();
alpar@1
   109
  void inc_nodes_size(int n);
alpar@1
   110
  
alpar@1
   111
 public:
alpar@1
   112
  int NodeNum() {return nodenum;};
alpar@1
   113
  int EdgeNum();
alpar@3
   114
  int MaxNode() const {return nodes_size;};
alpar@3
   115
  int FirstNode() const {return firstnode;};
alpar@3
   116
  int NextNode(int n) const {return nodes[n].next;};
alpar@3
   117
  int PrevNode(int n) const {return nodes[n].prev;};
alpar@3
   118
  N& operator()(int n) const {return *(N*)(nodes[n].data);};
alpar@3
   119
  N& Data      (int n) const {return *(N*)(nodes[n].data);};
alpar@1
   120
  int AddNode();
alpar@3
   121
  void AddNodeBlock(int n) const {for(int i=0;i<n;i++) AddNode();}
alpar@1
   122
  int AddNode(int n);
alpar@1
   123
  void Delete(int n);
alpar@3
   124
  int isaNode(int n) const 
alpar@3
   125
        {return n>=0&&n<nodes_size&&nodes[n].indeg!=FREE_NODE;};
alpar@1
   126
  
alpar@3
   127
  int InDeg(int n) const {return nodes[n].indeg;};
alpar@3
   128
  int OutDeg(int n) const {return nodes[n].outdeg;};
alpar@3
   129
  EdgePoint FirstIn(int n) const {return nodes[n].firstin;};
alpar@3
   130
  EdgePoint FirstOut(int n) const {return nodes[n].firstout;};
alpar@1
   131
alpar@3
   132
  E& operator()(EdgePoint e) const {return *(E*)(((edge_t*)e)->data);};
alpar@3
   133
  E& Data      (EdgePoint e) const {return *(E*)(((edge_t*)e)->data);};
alpar@3
   134
  int From(EdgePoint e) const {return e->from;};
alpar@3
   135
  int To(EdgePoint e) const {return e->to;};
alpar@3
   136
  EdgePoint NextIn(EdgePoint e) const 
alpar@1
   137
    {return e->nextin;};
alpar@3
   138
  EdgePoint NextOut(EdgePoint e)const 
alpar@1
   139
    {return e->nextout;};
alpar@1
   140
  EdgePoint AddEdge(int f, int t);
alpar@1
   141
  void Delete(EdgePoint e);
alpar@1
   142
  EdgePoint Edge(int f,int t);
alpar@1
   143
  //  EdgePoint Edge(E &d)
alpar@1
   144
  //    {return (EdgePoint)(((char*)&d)-(char*)&(((edge_t*)NULL)->data));};
alpar@3
   145
  E& operator()(int f, int t) const {return *(E*)(((edge_t*)Edge(f,t))->data);};
alpar@3
   146
  E& Data(int f, int t) const {return *(E*)(((edge_t*)Edge(f,t))->data);};
alpar@1
   147
  void Delete(int f, int t) {Delete(Edge(f,t));};
alpar@1
   148
  void Reverse(EdgePoint e);
alpar@1
   149
alpar@1
   150
  // Functions for EdgeIndex
alpar@1
   151
  
alpar@3
   152
  EdgePoint Edge(EdgeIndex i) const 
alpar@1
   153
    { return (EdgePoint)(edges[i.block]->fields+i.index);};
alpar@3
   154
  EdgeIndex Index(EdgePoint e) const { return e->index;};
alpar@3
   155
  EdgeIndex Index(int f, int t) const { EdgePoint e; return Edge(f,t)->index; }
alpar@1
   156
  void Delete(EdgeIndex i) { Delete(Edge(i));};
alpar@3
   157
  E& operator()(EdgeIndex i) const 
alpar@1
   158
     {return *(E*)(edges[i.block]->fields[i.index].data);};
alpar@3
   159
  E& Data(EdgeIndex i) const 
alpar@1
   160
     {return *(E*)(edges[i.block]->fields[i.index].data);};
alpar@1
   161
  EdgePoint AddEdge(int f, int t,EdgeIndex in);
alpar@1
   162
  
alpar@1
   163
alpar@1
   164
  
alpar@1
   165
  // Operators for symmetric graphs:
alpar@1
   166
alpar@3
   167
  EdgePoint FirstEdge(int n) const 
alpar@1
   168
    { return (EdgePoint)(FirstIn(n)?FirstIn(n):FirstOut(n));};
alpar@3
   169
  EdgePoint NextEdge(int n,EdgePoint e) const 
alpar@1
   170
    { return From(e)==n?NextOut(e):(NextIn(e)?NextIn(e):FirstOut(n)); };
alpar@3
   171
  int Opposite(EdgePoint e,int n) const 
alpar@1
   172
    { return From(e)+To(e)-n; };
alpar@1
   173
  
alpar@1
   174
  // Initializers, destructors
alpar@1
   175
       
alpar@1
   176
  OldGraph() {setup();};
alpar@1
   177
  OldGraph(int nosi) {setup(nosi);};
alpar@1
   178
  OldGraph(OldGraph<N,E> &H) {setup();operator=(H);};
alpar@1
   179
  ~OldGraph() {destroy();};  
alpar@1
   180
  void Clean(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);};
alpar@1
   181
  void Clear(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);};
alpar@1
   182
alpar@1
   183
  void DeleteEdges();
alpar@1
   184
    
alpar@1
   185
  OldGraph<N,E> &operator=(OldGraph<N,E> &H);
alpar@1
   186
};
alpar@1
   187
alpar@1
   188
//////////////////////////////////////////////////////////////////////
alpar@1
   189
// Template Definitions
alpar@1
   190
//////////////////////////////////////////////////////////////////////
alpar@1
   191
alpar@1
   192
//#include <stdio.h>
alpar@1
   193
alpar@1
   194
//**********************************************************************
alpar@1
   195
//                          OldGraph definitions
alpar@1
   196
//**********************************************************************
alpar@1
   197
alpar@1
   198
template<class N, class E> void OldGraph<N,E>::setup(int nosi) {
alpar@1
   199
  int i;
alpar@1
   200
alpar@1
   201
  //Set up nodes
alpar@1
   202
  nodenum = 0;
alpar@1
   203
  nodes_size = nosi;
alpar@1
   204
  // nodes = (nodes_t*) new char[sizeof(nodes_t)*nodes_size];
alpar@1
   205
  nodes = (nodes_t*) new nodes_t [nodes_size];
alpar@1
   206
  for(i=0;i<nodes_size;i++)
alpar@1
   207
    {
alpar@1
   208
      nodes[i].prev=i-1;
alpar@1
   209
      nodes[i].next=i+1;
alpar@1
   210
      nodes[i].indeg=FREE_NODE;
alpar@1
   211
      nodes[i].outdeg=0;
alpar@1
   212
      nodes[i].firstin=nodes[i].firstout=NULL;
alpar@1
   213
    }
alpar@1
   214
  firstnode=nodes[0].prev=nodes[nodes_size-1].next=INVALID;
alpar@1
   215
  freenodes=0;
alpar@1
   216
  //Set up edge-list_template_type;
alpar@1
   217
  freeedges = NULL;
alpar@1
   218
  
alpar@1
   219
  edges = new edge_block* [edge_block_max=INIT_EDGES_BLOCK_MAX];
alpar@1
   220
  edge_block_num = 0;
alpar@1
   221
  
alpar@1
   222
}
alpar@1
   223
alpar@1
   224
template<class N, class E> void OldGraph<N,E>::destroy()
alpar@1
   225
{
alpar@1
   226
  int i;
alpar@1
   227
  
alpar@1
   228
  while(firstnode!=INVALID) Delete(firstnode);
alpar@1
   229
  delete [] nodes;
alpar@1
   230
  for(i=0;i<edge_block_num;i++) delete edges[i];
alpar@1
   231
  delete [] edges;
alpar@1
   232
}
alpar@1
   233
alpar@1
   234
template<class N, class E> void OldGraph<N,E>::inc_nodes_size(int n)
alpar@1
   235
{
alpar@1
   236
  int i;
alpar@1
   237
  if(n<=nodenum) return;
alpar@1
   238
  
alpar@1
   239
  nodes_t *nn;
alpar@1
   240
//  nn = (nodes_t*) new char [sizeof(nodes_t)*n];
alpar@1
   241
  nn = (nodes_t*) new nodes_t [n];
alpar@1
   242
  for(i=0;i<nodes_size;i++)
alpar@1
   243
    {
alpar@1
   244
      nn[i].Copy(nodes[i]);
alpar@1
   245
      if(nodes[i].indeg!=FREE_NODE) ((N*)(nodes[i].data))->~N();
alpar@1
   246
    }
alpar@1
   247
  
alpar@1
   248
  delete [] nodes;
alpar@1
   249
  nodes = nn;
alpar@1
   250
  for(i=nodes_size;i<n;i++)
alpar@1
   251
    {
alpar@1
   252
      nodes[i].prev=i-1;
alpar@1
   253
      nodes[i].next=i+1;
alpar@1
   254
      nodes[i].indeg=FREE_NODE;
alpar@1
   255
      nodes[i].outdeg=0;
alpar@1
   256
      nodes[i].firstin=nodes[i].firstout=NULL;
alpar@1
   257
    }
alpar@1
   258
  nodes[nodes_size].prev=INVALID;
alpar@1
   259
  nodes[n-1].next=freenodes;
alpar@1
   260
  if(freenodes!=INVALID) nodes[freenodes].prev=n-1;
alpar@1
   261
  freenodes=nodes_size;
alpar@1
   262
  nodes_size=n;
alpar@1
   263
}
alpar@1
   264
alpar@1
   265
template<class N, class E> OldGraph<N,E> &OldGraph<N,E>::operator=(OldGraph<N,E> &H)
alpar@1
   266
{
alpar@1
   267
  Clean();
alpar@1
   268
alpar@1
   269
  int i;
alpar@1
   270
  EdgePoint e;
alpar@1
   271
  
alpar@1
   272
  for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i))
alpar@1
   273
    {
alpar@1
   274
      AddNode(i);
alpar@1
   275
      operator()(i)=H(i);
alpar@1
   276
    }
alpar@1
   277
  for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i))
alpar@1
   278
    for(e=H.FirstOut(i);e;e=H.NextOut(e))
alpar@1
   279
      operator()(AddEdge(i,H.To(e),H.Index(e)))=H(e);
alpar@1
   280
alpar@1
   281
   return *this;
alpar@1
   282
}
alpar@1
   283
alpar@1
   284
template<class N, class E> int OldGraph<N,E>::EdgeNum()
alpar@1
   285
{
alpar@1
   286
  int n=firstnode, m=0;
alpar@1
   287
  EdgePoint e;
alpar@1
   288
  while(n != INVALID)
alpar@1
   289
  {    
alpar@1
   290
    e=FirstOut(n);
alpar@1
   291
    while (e != NULL)
alpar@1
   292
    {
alpar@1
   293
      m++;
alpar@1
   294
      e=NextOut(e);
alpar@1
   295
    }
alpar@1
   296
    n=nodes[n].next;
alpar@1
   297
  }
alpar@1
   298
  return m;
alpar@1
   299
}
alpar@1
   300
alpar@1
   301
template<class N, class E> int OldGraph<N,E>::AddNode()
alpar@1
   302
{
alpar@1
   303
  int i;
alpar@1
   304
  
alpar@1
   305
  if(freenodes==INVALID) inc_nodes_size(2*nodes_size);
alpar@1
   306
  
alpar@1
   307
  i=freenodes;
alpar@1
   308
  if(firstnode!=INVALID) nodes[firstnode].prev=i;
alpar@1
   309
  freenodes=nodes[i].next;
alpar@1
   310
  new(nodes[i].data) N;  //Explicit constructor call
alpar@1
   311
  nodes[i].next=firstnode;
alpar@1
   312
  nodes[i].prev=INVALID;
alpar@1
   313
  nodes[i].indeg=0;
alpar@1
   314
  firstnode=i;
alpar@1
   315
  if(freenodes!=INVALID) nodes[freenodes].prev=INVALID;
alpar@1
   316
  nodenum++;
alpar@1
   317
  return i;
alpar@1
   318
}
alpar@1
   319
alpar@1
   320
template<class N, class E> int OldGraph<N,E>::AddNode(int n)
alpar@1
   321
{
alpar@1
   322
  int i;
alpar@1
   323
  
alpar@1
   324
  if(n>=nodes_size)
alpar@1
   325
    {
alpar@1
   326
      for(i=INIT_NODES_SIZE;i<=n;i*=2) ;
alpar@1
   327
      inc_nodes_size(i);
alpar@1
   328
    }
alpar@1
   329
  
alpar@1
   330
  if(nodes[n].indeg==FREE_NODE)
alpar@1
   331
    {
alpar@1
   332
      new(nodes[n].data) N;  //Explicit constructor call
alpar@1
   333
      if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@1
   334
      if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next = nodes[n].next;
alpar@1
   335
      else freenodes = nodes[n].next;
alpar@1
   336
      
alpar@1
   337
      nodes[n].prev = INVALID;
alpar@1
   338
      if((nodes[n].next = firstnode)!=INVALID) nodes[firstnode].prev=n;
alpar@1
   339
      firstnode = n;
alpar@1
   340
      nodenum++;
alpar@1
   341
      nodes[n].indeg=0;
alpar@1
   342
    }
alpar@1
   343
  return n;
alpar@1
   344
}
alpar@1
   345
alpar@1
   346
template<class N, class E> void OldGraph<N,E>::Delete(int n)
alpar@1
   347
{
alpar@1
   348
  if(n==INVALID||nodes[n].indeg==FREE_NODE) return;
alpar@1
   349
alpar@1
   350
  EdgePoint e;
alpar@1
   351
  
alpar@1
   352
  while(e=FirstIn(n)) Delete(e);
alpar@1
   353
  while(e=FirstOut(n)) Delete(e);
alpar@1
   354
  
alpar@1
   355
  if(n==firstnode) firstnode=nodes[n].next;
alpar@1
   356
  if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next=nodes[n].next;
alpar@1
   357
  if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev=nodes[n].prev;
alpar@1
   358
  if(freenodes!=INVALID) nodes[freenodes].prev=n;
alpar@1
   359
  nodes[n].next=freenodes;
alpar@1
   360
  nodes[n].prev=INVALID;
alpar@1
   361
  nodes[n].indeg=FREE_NODE;
alpar@1
   362
  ((N*)(nodes[n].data))->~N();  //Explicit destructor call
alpar@1
   363
  freenodes=n;
alpar@1
   364
alpar@1
   365
  nodenum--;
alpar@1
   366
}
alpar@1
   367
alpar@1
   368
template<class N, class E> EdgePoint OldGraph<N,E>::AddEdge(int f, int t)
alpar@1
   369
{
alpar@1
   370
  int i;
alpar@1
   371
  edge_block *peb;
alpar@1
   372
  edge_block **ppeb;
alpar@1
   373
  edge_t *e;
alpar@1
   374
  
alpar@1
   375
  if(!freeedges)
alpar@1
   376
    {
alpar@1
   377
      if(edge_block_num>=edge_block_max)
alpar@1
   378
	{
alpar@1
   379
	  ppeb = new edge_block* [edge_block_max*=2];
alpar@1
   380
	  for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i];
alpar@1
   381
	  delete [] edges;
alpar@1
   382
	  edges = ppeb;
alpar@1
   383
	}
alpar@1
   384
      peb = new edge_block;
alpar@1
   385
      edges[edge_block_num] = peb;
alpar@1
   386
      
alpar@1
   387
      for(i=0;i<EDGE_BLOCK_SIZE;i++)
alpar@1
   388
	{
alpar@1
   389
	  ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1);
alpar@1
   390
	  ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1);
alpar@1
   391
	  ((edge_t*)peb->fields)[i].index.block = edge_block_num;
alpar@1
   392
	  ((edge_t*)peb->fields)[i].index.index = i;
alpar@1
   393
	  ((edge_t*)peb->fields)[i].from = INVALID;
alpar@1
   394
	}
alpar@1
   395
      ((edge_t*)peb->fields)[0].previn=
alpar@1
   396
	((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=NULL;
alpar@1
   397
      freeedges = (edge_t*)peb->fields;
alpar@1
   398
      edge_block_num++;
alpar@1
   399
    }
alpar@1
   400
  
alpar@1
   401
  e=(edge_t *)freeedges;
alpar@1
   402
  new (e->data) E;  //Explicit constructor call
alpar@1
   403
  freeedges=e->nextin;
alpar@1
   404
  if(freeedges) freeedges->previn=NULL;
alpar@1
   405
  
alpar@1
   406
  e->from=f; e->to=t;
alpar@1
   407
  e->previn=e->prevout=NULL;
alpar@1
   408
  e->nextin=nodes[t].firstin;
alpar@1
   409
  e->nextout=nodes[f].firstout;
alpar@1
   410
  if(nodes[t].firstin) nodes[t].firstin->previn=e;
alpar@1
   411
  if(nodes[f].firstout) nodes[f].firstout->prevout=e;
alpar@1
   412
  nodes[t].firstin=nodes[f].firstout=e;
alpar@1
   413
  nodes[t].indeg++; nodes[f].outdeg++;
alpar@1
   414
alpar@1
   415
  return (EdgePoint)e;
alpar@1
   416
  
alpar@1
   417
}
alpar@1
   418
alpar@1
   419
template<class N, class E>
alpar@1
   420
EdgePoint OldGraph<N,E>::AddEdge(int f, int t, EdgeIndex in)
alpar@1
   421
{
alpar@1
   422
  int i;
alpar@1
   423
  edge_block *peb;
alpar@1
   424
  edge_block **ppeb;
alpar@1
   425
  edge_t *e;
alpar@1
   426
  
alpar@1
   427
  while(edge_block_num<=in.block)
alpar@1
   428
    {
alpar@1
   429
      if(edge_block_num>=edge_block_max)
alpar@1
   430
	{
alpar@1
   431
	  ppeb = new edge_block* [edge_block_max*=2];
alpar@1
   432
	  for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i];
alpar@1
   433
	  delete [] edges;
alpar@1
   434
	  edges = ppeb;
alpar@1
   435
	}
alpar@1
   436
      peb = new edge_block;
alpar@1
   437
      edges[edge_block_num] = peb;
alpar@1
   438
      
alpar@1
   439
      for(i=0;i<EDGE_BLOCK_SIZE;i++)
alpar@1
   440
	{
alpar@1
   441
	  ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1);
alpar@1
   442
	  ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1);
alpar@1
   443
	  ((edge_t*)peb->fields)[i].index.block = edge_block_num;
alpar@1
   444
	  ((edge_t*)peb->fields)[i].index.index = i;
alpar@1
   445
	  ((edge_t*)peb->fields)[i].from = INVALID;
alpar@1
   446
	}
alpar@1
   447
      ((edge_t*)peb->fields)[0].previn=NULL;
alpar@1
   448
      ((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=freeedges;
alpar@1
   449
      if(freeedges)
alpar@1
   450
	freeedges->previn = ((edge_t*)peb->fields) + (EDGE_BLOCK_SIZE-1);
alpar@1
   451
      freeedges = (edge_t*)peb->fields;
alpar@1
   452
      edge_block_num++;
alpar@1
   453
    }
alpar@1
   454
  
alpar@1
   455
  
alpar@1
   456
  e=((edge_t*)(edges[in.block]->fields))+in.index;
alpar@1
   457
  if(e->from==INVALID)
alpar@1
   458
    {
alpar@1
   459
      if(e->previn) e->previn->nextin = e->nextin;
alpar@1
   460
               else freeedges = e->nextin;
alpar@1
   461
      if(e->nextin) e->nextin->previn = e->previn;
alpar@1
   462
alpar@1
   463
      new (e->data) E;  //Explicit constructor call
alpar@1
   464
      
alpar@1
   465
      e->from=f; e->to=t;
alpar@1
   466
      e->previn=e->prevout=NULL;
alpar@1
   467
      e->nextin=nodes[t].firstin;
alpar@1
   468
      e->nextout=nodes[f].firstout;
alpar@1
   469
      if(nodes[t].firstin) nodes[t].firstin->previn=e;
alpar@1
   470
      if(nodes[f].firstout) nodes[f].firstout->prevout=e;
alpar@1
   471
      nodes[t].firstin=nodes[f].firstout=e;
alpar@1
   472
      nodes[t].indeg++; nodes[f].outdeg++;
alpar@1
   473
    }
alpar@1
   474
  return (EdgePoint)e;
alpar@1
   475
}
alpar@1
   476
alpar@1
   477
template<class N, class E> void OldGraph<N,E>::Delete(EdgePoint e)
alpar@1
   478
{
alpar@1
   479
  if(!e||e->from==INVALID) return;
alpar@1
   480
  
alpar@1
   481
  ((E*)(((edge_t*)e)->data))->~E();  //Explicit destructor call
alpar@1
   482
  
alpar@1
   483
  nodes[e->from].outdeg--; nodes[e->to].indeg--;
alpar@1
   484
alpar@1
   485
  
alpar@1
   486
  if(e->previn)
alpar@1
   487
    e->previn->nextin=e->nextin;
alpar@1
   488
  else nodes[e->to].firstin=e->nextin;
alpar@1
   489
  if(e->prevout)
alpar@1
   490
    e->prevout->nextout=e->nextout;
alpar@1
   491
  else nodes[e->from].firstout=e->nextout;
alpar@1
   492
  if(e->nextin)
alpar@1
   493
    e->nextin->previn=e->previn;
alpar@1
   494
  if(e->nextout)
alpar@1
   495
    e->nextout->prevout=e->prevout;
alpar@1
   496
  
alpar@1
   497
  if(freeedges) freeedges->previn=e;
alpar@1
   498
  e->previn=NULL; e->nextin=freeedges;
alpar@1
   499
alpar@1
   500
  e->from = INVALID;
alpar@1
   501
  freeedges=e;
alpar@1
   502
}
alpar@1
   503
alpar@1
   504
template<class N, class E> EdgePoint OldGraph<N,E>::Edge(int f, int t)
alpar@1
   505
{
alpar@1
   506
  EdgePoint e;
alpar@1
   507
  
alpar@1
   508
  for(e=nodes[f].firstout;e&&e->to!=t;e=e->nextout) ;
alpar@1
   509
  
alpar@1
   510
  return (EdgePoint) e;
alpar@1
   511
}
alpar@1
   512
alpar@1
   513
template<class N, class E> void OldGraph<N,E>::Reverse(EdgePoint e)
alpar@1
   514
{
alpar@1
   515
  if(!e) return;
alpar@1
   516
alpar@1
   517
  nodes[e->from].outdeg--; nodes[e->to].indeg--;
alpar@1
   518
  
alpar@1
   519
  if(e->previn)
alpar@1
   520
    e->previn->nextin=e->nextin;
alpar@1
   521
  else nodes[e->to].firstin=e->nextin;
alpar@1
   522
  if(e->prevout)
alpar@1
   523
    e->prevout->nextout=e->nextout;
alpar@1
   524
  else nodes[e->from].firstout=e->nextout;
alpar@1
   525
  if(e->nextin)
alpar@1
   526
    e->nextin->previn=e->previn;
alpar@1
   527
  if(e->nextout)
alpar@1
   528
    e->nextout->prevout=e->prevout;
alpar@1
   529
  
alpar@1
   530
  int t,f;
alpar@1
   531
  f=e->to;e->to=t=e->from;
alpar@1
   532
  e->from=f;
alpar@1
   533
alpar@1
   534
  e->previn=e->prevout=NULL;
alpar@1
   535
  e->nextin=nodes[t].firstin;
alpar@1
   536
  e->nextout=nodes[f].firstout;
alpar@1
   537
  if(nodes[t].firstin) nodes[t].firstin->previn=e;
alpar@1
   538
  if(nodes[f].firstout) nodes[f].firstout->prevout=e;
alpar@1
   539
  nodes[t].firstin=nodes[f].firstout=e;
alpar@1
   540
  nodes[t].indeg++; nodes[f].outdeg++;
alpar@1
   541
alpar@1
   542
}
alpar@1
   543
alpar@1
   544
template<class N, class E> void OldGraph<N,E>::DeleteEdges()
alpar@1
   545
{
alpar@1
   546
  int n;
alpar@1
   547
  for(n=FirstNode();n!=INVALID;n=NextNode(n))
alpar@1
   548
    while(FirstOut(n)) Delete(FirstOut(n));
alpar@1
   549
}
alpar@1
   550
alpar@1
   551
#endif