第七十三课 图的存储结构(下)

Posted wanmeishenghuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第七十三课 图的存储结构(下)相关的知识,希望对你有一定的参考价值。

技术分享图片

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

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

添加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 }

结果如下:

技术分享图片

 

 

小结:

技术分享图片

 

以上是关于第七十三课 图的存储结构(下)的主要内容,如果未能解决你的问题,请参考以下文章

第七十二课 图的存储结构(上)

第七十三天

python学习第七十三天:模板续

leetcode 简单 第七十三题 丑数

第七十三篇 jq进阶与bootstrap了解

第七十四课 图的遍历(BFS)