zoukankan      html  css  js  c++  java
  • 第七十三课 图的存储结构(下)

    增加新顶点的时候只能在链表的末尾进行,其他的顶点的编号不能打乱了。

    添加ListGraph.h文件:

      1 #ifndef LISTGRAPH_H
      2 #define LISTGRAPH_H
      3 
      4 #include "Graph.h"
      5 #include "LinkList.h"
      6 #include "Exception.h"
      7 #include "DynamicArray.h"
      8 
      9 namespace DTLib
     10 {
     11 
     12 template < typename V, typename E >
     13 class ListGraph : public Graph<V, E>
     14 {
     15 protected:
     16     struct Vertex : public Object   //定义顶点
     17     {
     18         V* data;
     19         LinkList< Edge<E> > edge;
     20 
     21         Vertex()
     22         {
     23             data = NULL;
     24         }
     25     };
     26 
     27     LinkList<Vertex*> m_list;   //真正的邻接链表
     28 public:
     29     ListGraph(unsigned int n = 0)
     30     {
     31         for(unsigned int i = 0; i < n; i++)
     32         {
     33             addVertex();
     34         }
     35     }
     36 
     37     int addVertex()
     38     {
     39         int ret = -1;
     40         Vertex* v = new Vertex();
     41 
     42         if( v != NULL )
     43         {
     44             m_list.insert(v);
     45 
     46             ret = m_list.length() - 1; //返回新增加的顶点的编号
     47         }
     48         else
     49         {
     50             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create Vertex object...");
     51         }
     52 
     53         return ret;
     54     }
     55 
     56     int addVertex(const V& value)
     57     {
     58         int ret = addVertex();
     59 
     60         if( ret >= 0 )
     61         {
     62             setVertex(ret, value);
     63         }
     64 
     65         return ret;
     66     }
     67 
     68     bool setVertex(int i, const V& value)
     69     {
     70         int ret = ((0 <= i) && (i < vCount()));
     71 
     72         if( ret )
     73         {
     74             Vertex* vertex = m_list.get(i);
     75             V* data = vertex->data;
     76 
     77             if( data == NULL )
     78             {
     79                 data = new V();
     80             }
     81 
     82             if( data != NULL )
     83             {
     84                 *data = value;
     85 
     86                 vertex->data = data;
     87             }
     88             else
     89             {
     90                 THROW_EXCEPTION(NoEnoughMemoryException, "Bo memory to create Vertex value...");
     91             }
     92         }
     93 
     94         return ret;
     95     }
     96 
     97     V getVertex(int i)
     98     {
     99         V ret;
    100 
    101         if( !getVertex(i, ret) )
    102         {
    103             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
    104         }
    105 
    106         return ret;
    107     }
    108 
    109     bool getVertex(int i, V& value)
    110     {
    111         int ret = ((0 <= i) && (i < vCount()));
    112 
    113         if( ret )
    114         {
    115             Vertex* v = m_list.get(i);
    116 
    117             if( v->data != NULL )
    118             {
    119                 value = *(v->data);
    120             }
    121             else
    122             {
    123                 THROW_EXCEPTION(InvalidOperationException, "No value assigned to this vertex...");
    124             }
    125         }
    126 
    127         return ret;
    128     }
    129 
    130     void removeVertex()  //删除最近添加的顶点,只能从后面的顶点开始删除
    131     {
    132         if( m_list.length() > 0 )
    133         {
    134             int index = m_list.length() - 1;
    135             Vertex* v = m_list.get(index);
    136 
    137             if( m_list.remove(index) )
    138             {
    139                 for(int i=(m_list.move(0), 0); !m_list.end(); i++, m_list.next())
    140                 {
    141                     int pos = m_list.current()->edge.find(Edge<E>(i, index));
    142 
    143                     if( pos >= 0 )
    144                     {
    145                         m_list.current()->edge.remove(pos);
    146                     }
    147                 }
    148 
    149                 delete v->data;
    150                 delete v;
    151             }
    152         }
    153         else
    154         {
    155             THROW_EXCEPTION(InvalidOperationException, "No vertex in current graph...");
    156         }
    157     }
    158 
    159     SharedPointer< Array<int> > getAdjacent(int i)
    160     {
    161         DynamicArray<int>* ret = NULL;
    162 
    163         if( (0 <= i) && (i < vCount()) )
    164         {
    165             Vertex* vertex = m_list.get(i);
    166 
    167             ret = new DynamicArray<int>(vertex->edge.length());
    168 
    169             if( ret != NULL )
    170             {
    171                 for(int k=(vertex->edge.move(0), 0); !vertex->edge.end(); k++, vertex->edge.next())
    172                 {
    173                     ret->set(k, vertex->edge.current().e);
    174                 }
    175             }
    176             else
    177             {
    178                 THROW_EXCEPTION(NoEnoughMemoryException ,"No memory to create DynamicArray<int>...");
    179             }
    180         }
    181         else
    182         {
    183             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
    184         }
    185 
    186         return ret;
    187     }
    188 
    189     E getEdge(int i, int j)
    190     {
    191         E ret;
    192 
    193         if( !getEdge(i, j, ret) )
    194         {
    195             THROW_EXCEPTION(InvalidParameterException, "Edge<i, j> is invalid...");
    196         }
    197 
    198         return ret;
    199     }
    200 
    201     bool getEdge(int i, int j, E& value)
    202     {
    203         int ret = ( (0 <= i) && (i < vCount()) &&
    204                     (0 <= j) && (j < vCount()) );
    205 
    206         if( ret )
    207         {
    208             Vertex* vertex = m_list.get(i);
    209             int pos = vertex->edge.find(Edge<E>(i, j));
    210 
    211             if( pos >= 0 )
    212             {
    213                 value = vertex->edge.get(pos).data;
    214             }
    215             else
    216             {
    217                 THROW_EXCEPTION(InvalidOperationException, "No value assigned to this edge...");
    218             }
    219         }
    220 
    221         return ret;
    222     }
    223 
    224     bool setEdge(int i, int j, const E& value)
    225     {
    226         int ret = ( (0 <= i) && (i < vCount()) &&
    227                     (0 <= j) && (j < vCount()) );
    228 
    229         if( ret )
    230         {
    231             Vertex* vertex = m_list.get(i);
    232             int pos = vertex->edge.find(Edge<E>(i, j));
    233 
    234             if( pos >= 0 )
    235             {
    236                 ret = vertex->edge.set(pos, Edge<E>(i, j, value));
    237             }
    238             else
    239             {
    240                 ret = vertex->edge.insert(0, Edge<E>(i, j, value));
    241             }
    242         }
    243 
    244         return ret;
    245     }
    246 
    247     bool removeEdge(int i, int j)
    248     {
    249         int ret = ( (0 <= i) && (i < vCount()) &&
    250                     (0 <= j) && (j < vCount()) );
    251 
    252         if( ret )
    253         {
    254             Vertex* vertex = m_list.get(i);
    255             int pos = vertex->edge.find(Edge<E>(i, j));
    256 
    257             if( pos >= 0 )
    258             {
    259                 ret = vertex->edge.remove(pos);
    260             }
    261         }
    262 
    263         return ret;
    264     }
    265 
    266     int vCount()
    267     {
    268         return m_list.length();
    269     }
    270 
    271     int eCount()
    272     {
    273         int ret = 0;
    274 
    275         for(m_list.move(0); !m_list.end(); m_list.next())
    276         {
    277             ret += m_list.current()->edge.length();
    278         }
    279 
    280         return ret;
    281     }
    282 
    283     int ID(int i)
    284     {
    285         int ret = 0;
    286 
    287         if( (0 <= i) && (i < vCount()) )
    288         {
    289             for(m_list.move(0); !m_list.end(); m_list.next())
    290             {
    291                 LinkList< Edge<E> >& edge = m_list.current()->edge;
    292 
    293                 for(edge.move(0); !edge.end(); edge.next())
    294                 {
    295                     if( edge.current().e == i )
    296                     {
    297                         ret++;
    298                         break;
    299                     }
    300                 }
    301             }
    302         }
    303         else
    304         {
    305             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
    306         }
    307 
    308         return ret;
    309     }
    310 
    311     int OD(int i)
    312     {
    313         int ret = 0;
    314 
    315         if( (0 <= i) && (i < vCount()) )
    316         {
    317             ret = m_list.get(i)->edge.length();
    318         }
    319         else
    320         {
    321             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
    322         }
    323 
    324         return ret;
    325     }
    326 
    327     ~ListGraph()
    328     {
    329         while( m_list.length() > 0 )
    330         {
    331             Vertex* toDel = m_list.get(0);
    332 
    333             m_list.remove(0);
    334 
    335             delete toDel->data;
    336             delete toDel;
    337         }
    338     }
    339 };
    340 
    341 }
    342 
    343 #endif // LISTGRAPH_H

    测试程序如下:

     1 #include <iostream>
     2 #include "BTreeNode.h"
     3 #include "ListGraph.h"
     4 
     5 using namespace std;
     6 using namespace DTLib;
     7 
     8 
     9 int main()
    10 {
    11     ListGraph<char, int> g;
    12 
    13     g.addVertex('A');
    14     g.addVertex('B');
    15     g.addVertex('C');
    16     g.addVertex('D');
    17 
    18     for(int i=0; i< g.vCount(); i++)
    19     {
    20         cout << i << " : " << g.getVertex(i) << endl;
    21     }
    22 
    23     g.setEdge(0, 1, 5);
    24     g.setEdge(0, 3, 5);
    25     g.setEdge(1, 2, 8);
    26     g.setEdge(2, 3, 2);
    27     g.setEdge(3, 1, 9);
    28 
    29     cout << "W(0, 1) : " << g.getEdge(0, 1) << endl;
    30     cout << "W(0, 3) : " << g.getEdge(0, 3) << endl;
    31     cout << "W(1, 2) : " << g.getEdge(1, 2) << endl;
    32     cout << "W(2, 3) : " << g.getEdge(2, 3) << endl;
    33     cout << "W(3, 1) : " << g.getEdge(3, 1) << endl;
    34 
    35     cout << "eCount : " << g.eCount() << endl;
    36 
    37     SharedPointer< Array<int> > aj = g.getAdjacent(0);
    38 
    39     for(int i=0; i<aj->length(); i++)
    40     {
    41         cout << (*aj)[i] << endl;
    42     }
    43 
    44     cout << "ID(1) : " << g.ID(1) << endl;
    45     cout << "OD(1) : " << g.OD(1) << endl;
    46     cout << "TD(1) : " << g.TD(1) << endl;
    47 
    48     g.removeVertex();
    49 
    50     cout << "eCount : " << g.eCount() << endl;
    51 
    52     cout << "W(0, 1) : " << g.getEdge(0, 1) << endl;
    53     cout << "W(1, 2) : " << g.getEdge(1, 2) << endl;
    54 
    55     return 0;
    56 }

    结果如下:

    小结:

  • 相关阅读:
    对象不支持此属性或方法
    继承多态
    GetType和typeof的区别
    比较高效的表格行背景变色及选定高亮JS
    C#获取存储过程的Return返回值和Output输出参数值
    删除表中重复记录,只保留一行
    实现自定义的ToolTip
    状态管理之Cookie
    Microsoft SQL Server,错误: 5120
    IE/Firefox中全局正则表达式的兼容
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9710534.html
Copyright © 2011-2022 走看看