数据结构--无向图--初级版

其实图的存储结构很简单,常见的就是邻接表和邻接矩阵。

个人觉得,比较复杂的是求最短路径之类的算法。

下面先发一个基础版的,实现了深度和广度优先遍历。

但这里的遍历方法和大多数教科书上有了一点区别,就是没有用递归,而是用栈代替了。因为递归是讲所谓的“现场”保存到调用栈中,而调用栈好像很小,很容易溢出。

但这个版本也存在一些效率问题,我会在注释里写出

里面使用的liststock其实就是封装了一个前面介绍的链表类。很简单

 

  1  #pragma  once;
  2  #include  < iostream >
  3  #include  " mylist.h "
  4  #include  " liststack.h "
  5 
  6  /* ********************************************************************** */
  7  /*  用邻接表结构实现图                                                                                                       */
  8  /* ********************************************************************** */
  9 
 10  template < typename T >
 11  struct  vertex
 12  {
 13      T data;
 14       int  nWeight;
 15      mylist < int >  borders;
 16  };
 17 
 18  const   int  MAX_VERTEX_COUNT  =   6 ;
 19 
 20  template < typename T >
 21  class  mygraph
 22  {
 23  public :
 24      mygraph()
 25      {
 26          m_size  =  MAX_VERTEX_COUNT;
 27 
 28      }
 29 
 30       void  setVertexData( int  nVertex,  const  T &  data,  int  nWeight)
 31      {
 32           if (nVertex  >=  m_size)
 33          {
 34               throw ( " 超出顶点数量 " );
 35          }
 36          m_vertexlist[nVertex].data  =  data;
 37          m_vertexlist[nVertex].nWeight  =  nWeight;
 38      }
 39 
 40       void  addBorder( int  nVertex,  int  nRelation)
 41      {
 42           if (nVertex  >=  m_size  ||  nRelation  >=  m_size)
 43          {
 44               throw ( " 超出顶点数量 " );
 45          }
 46          _addBorder(nVertex, nRelation);
 47          _addBorder(nRelation, nVertex);
 48           // 无向图,需要同时设置两个顶点的关系
 49      }
 50 
 51       // 广度优先遍历
 52       void  BFS( int  nFirstVertex)
 53      {
 54           bool  visitRecord[MAX_VERTEX_COUNT];
 55          liststack < int >  searchStack;
 56 
 57 
 58          
 59          searchStack.push(nFirstVertex);
 60           while ( ! searchStack.empty())
 61          {
 62               int  nCurrentVertex  =  searchStack.pop();
 63 
 64              visitRecord[nCurrentVertex]  =   true ;
 65              
 66              mylist < int > ::Iterator iBegin  =  m_vertexlist[nCurrentVertex].borders.begin();
 67               while (iBegin  !=  m_vertexlist[nCurrentVertex].borders.end())
 68              {
 69                   if ( ! visitRecord[ * iBegin])
 70                  {
 71                      visitRecord[ * iBegin]  =   true ;
 72                       //
 73                      searchStack.push( * iBegin);
 74                      cout <<  nCurrentVertex  <<   " -- "   <<    * iBegin  <<  endl;
 75                      
 76                  }
 77                  iBegin  ++ ;
 78              }
 79          
 80          }
 81 
 82          
 83      }
 84 
 85       // 深度优先遍历
 86       void  DFS( int  nFirstVertex)
 87      {
 88           bool  visitRecord[MAX_VERTEX_COUNT];
 89          liststack < int >  searchStack;
 90 
 91           int  i;
 92           for (i  =   0 ; i  <  m_size; i  ++ )
 93          {
 94              visitRecord[i]  =   false ;
 95          }
 96          
 97      
 98          
 99           while ( ! searchStack.empty())
100          {
101               int  nCurrentVertex  =  searchStack.top();
102 
103              visitRecord[nCurrentVertex]  =   true ;
104          
105              mylist < int > ::Iterator iBegin  =  m_vertexlist[nCurrentVertex].borders.begin();
106 
107               // 这里就存在一个效率问题,每次都从邻接表的头开始遍历。
108               // 但之所以没有保存链表中的迭代器对象,是担心在多线程操作中,
109               // 可能一个线程遍历,另一个线程在给图增加定点。
110               // 虽然这个实现版本中定点数是固定的,但绝对很容易就改成可动态增长的。
111               // 一旦数组动态增长,那么链表中的指针就会变为无效。
112               // 大家都知道,复制指针是很危险的,除非用灵巧指针代替。
113               // 今后的版本中会修改这个问题
114               while (iBegin  !=  m_vertexlist[nCurrentVertex].borders.end())
115              {
116                   if ( ! visitRecord[ * iBegin])
117                  {
118                      visitRecord[ * iBegin]  =   true ;
119                      searchStack.push( * iBegin);
120                      cout  <<  nCurrentVertex  <<   " - "   <<   * iBegin  <<  endl;
121                       break ;
122                  }
123                  iBegin  ++ ;
124              }
125               if (iBegin  ==  m_vertexlist[nCurrentVertex].borders.end())
126              {
127                  
128                  searchStack.pop();
129              }
130          }
131      }
132 
133  private :
134       void  _addBorder( int  nVertex,  int  nRelation)
135      {
136 
137           if ( ! (m_vertexlist[nVertex].borders.find(nRelation)  ==  m_vertexlist[nVertex].borders.end()))
138          {
139               return  ;
140          }
141 
142          m_vertexlist[nVertex].borders.insert(nRelation);
143      }
144      size_t m_size;
145      vertex < T >  m_vertexlist[MAX_VERTEX_COUNT];
146 
147  };

你可能感兴趣的:(数据结构--无向图--初级版)