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

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

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

结果如下:

小结:

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9710534.html

时间: 2024-08-29 11:32:02

第七十三课 图的存储结构(下)的相关文章

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

顶点和数据元素相关联: 每个顶点关联着一个字符串,这个就是顶点的数据,这个数据关联着工程意义. 添加MatrixGraph.h文件: 1 #ifndef MATRIXGRAPH_H 2 #define MATRIXGRAPH_H 3 4 #include "Graph.h" 5 #include "Exception.h" 6 #include "DynamicArray.h" 7 8 namespace DTLib 9 { 10 // V是顶点

《大话数据结构》笔记(7-2)--图:存储结构

第七章  图 图的存储结构 图不能用简单的顺序存储结构来表示. 而多重链表的方式,即以一个数据域和多个指针域组成的结点表示图中的一个顶点,尽管可以实现图结构,但是会有问题,比如若各个顶点的度数相差很大,按度数最大的顶点设计结点结构会造成很多存储单元的浪费,而若按每个顶点自己的度数设计不同的顶点结构,又带来操作的不便. 对于图来说,如何对它实现物理存储是个难题.图有以下五种不同的存储结构. 邻接矩阵 图的邻接矩阵(Adjacency Matrix)存储方式使用过两个数组来表示图.一个一维数组存储图

图的存储结构(邻接矩阵)

图的存储结构(邻接矩阵) 让编程改变世界 Change the world by program 图的存储结构 图的存储结构相比较线性表与树来说就复杂很多. 我们回顾下,对于线性表来说,是一对一的关系,所以用数组或者链表均可简单存放.树结构是一对多的关系,所以我们要将数组和链表的特性结合在一起才能更好的存放. 那么我们的图,是多对多的情况,另外图上的任何一个顶点都可以被看作是第一个顶点,任一顶点的邻接点之间也不存在次序关系. 我们仔细观察以下几张图,然后深刻领悟一下: 因为任意两个顶点之间都可能

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

数据结构之图(一)图的存储结构

图的存储结构相对于线性表和树来说更为复杂,因为图中的顶点具有相对概念,没有固定的位置.那我们怎么存储图的数据结构呢?我们知道,图是由(V, E)来表示的,对于无向图来说,其中 V = (v0, v1, ... , vn),E = { (vi,vj) (0 <=  i, j <=  n且i 不等于j)},对于有向图,E = { < vi,vj > (0 <=  i, j <=  n且i 不等于j)}.V是顶点的集合,E是边的集合.所以我们只要把顶点和边的集合储存起来,那么

数据结构 - 图的存储结构

图的抽象数据类型定义 图是一种数据结构,加上一组基本操作就构成了图的抽象数据类型. 图的抽象数据类型定义如下: ADT Graph{ 数据对象V:具有相同特性的数据元素的集合,称为顶点集. 数据关系R:R={VR} VR={<v,w>|<v,w>| v,w?V∧p(v,w) ,<v,w>表示 从v到w的弧,P(v,w)定义了弧<v,w>的信息 } 基本操作P: Create_Graph() : 图的创建操作. 初始条件:无. 操作结果:生成一个没有顶点的空图

(转)数据结构之图(存储结构、遍历)

一.图的存储结构 1.1 邻接矩阵 图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 看一个实例,下图左就是一个无向图. 从上面可以看出,无向图的边数组是一个对称矩阵.所谓对称矩阵就是n阶矩阵的元满足aij = aji.即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的. 从这个矩阵中,很容易知道图中的信息. (1)要判断任意两顶点是否有

图的存储结构及遍历

一.图的存储结构 1.1 邻接矩阵 图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 看一个实例,下图左就是一个无向图. 从上面可以看出,无向图的边数组是一个对称矩阵.所谓对称矩阵就是n阶矩阵的元满足aij = aji.即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的. 从这个矩阵中,很容易知道图中的信息. (1)要判断任意两顶点是否有

数据结构(五)图---图的存储结构5种

一:图的抽象数据类型 ADT 图(Graph) Data 顶点的有穷非空集合和边的集合 Operation CreateGraph(*G,V,VR):按照顶点集V和边弧集VR的定义构造图G DestroyGraph(*G):图G存在则销毁 LocateVex(G,u):若图G中存在顶点u,则返回图中位置 GetVex(G,v):返回图中顶点v的值 PutVex(G,v,value):将图G中顶点v赋值给value FirstAdjVex(G,*v):返回顶点v的一个邻接顶点,若顶点在G中无邻接顶