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

顶点和数据元素相关联:

每个顶点关联着一个字符串,这个就是顶点的数据,这个数据关联着工程意义。

添加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是顶点类型,E是边的类型
 11 template < int N, typename V, typename E >
 12 class MatrixGraph : public Graph<V, E>
 13 {
 14 protected:
 15     V* m_vertexes[N];
 16     E* m_edges[N][N];
 17     int m_eCount;
 18 public:
 19     MatrixGraph()
 20     {
 21         for(int i = 0; i < vCount(); i++)
 22         {
 23             m_vertexes[i] = NULL;
 24
 25             for( int j = 0; j < vCount(); j++)
 26             {
 27                 m_edges[i][j] = NULL;
 28             }
 29         }
 30
 31         m_eCount = 0;
 32     }
 33
 34     V getVertex(int i)
 35     {
 36         V ret;
 37
 38         if( !getVertex(i, ret) )
 39         {
 40             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
 41         }
 42
 43         return ret;
 44     }
 45
 46     bool getVertex(int i, V& value)
 47     {
 48         bool ret = ((0 <= i) && (i < vCount()));
 49
 50         if( ret )
 51         {
 52             if( m_vertexes[i] != NULL )
 53             {
 54                 value = *(m_vertexes[i]);
 55             }
 56             else
 57             {
 58                 THROW_EXCEPTION(InvalidOperationException, "No value assigned to this vertex...");
 59             }
 60         }
 61
 62         return ret;
 63     }
 64     bool setVertex(int i, const V& value)
 65     {
 66         bool ret = ((0 <= i) && (i < vCount()));
 67
 68         if( ret )
 69         {
 70             V* data = m_vertexes[i];
 71
 72             if( data == NULL )
 73             {
 74                 data = new V();
 75             }
 76
 77             if( data != NULL )
 78             {
 79                 *data = value;
 80
 81                 m_vertexes[i] = data;  //引入data为了异常安全
 82             }
 83             else
 84             {
 85                 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to store new vertex value...");
 86             }
 87         }
 88
 89         return ret;
 90     }
 91
 92     SharedPointer< Array<int> > getAdjacent(int i) //获取i的邻接顶点
 93     {
 94         DynamicArray<int>* ret = NULL;
 95
 96         if( (0 <= i) && (i < vCount()) )
 97         {
 98             int n = 0;
 99
100             for(int j = 0; j < vCount(); j++)
101             {
102                 if( m_edges[i][j] != NULL )
103                 {
104                     n++;
105                 }
106             }
107
108             ret = new DynamicArray<int>(n);
109
110             if( ret != NULL )
111             {
112                 for(int j=0,k=0; j<vCount(); j++)
113                 {
114                     if( m_edges[i][j] != NULL )
115                     {
116                         ret->set(k++, j);
117                     }
118                 }
119             }
120             else
121             {
122                 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new ret object...");
123             }
124         }
125         else
126         {
127             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
128         }
129
130         return ret;
131     }
132
133     E getEdge(int i, int j)
134     {
135         E ret;
136
137         if( !getEdge(i, j, ret) )
138         {
139             THROW_EXCEPTION(InvalidParameterException, "Index <i,j> is invalid...");
140         }
141
142         return ret;
143     }
144
145     bool getEdge(int i, int j, E& value)
146     {
147         bool ret = ((0 <= i) && (i < vCount()) &&
148                     (0 <= j) && (j < vCount()) );
149
150         if( ret )
151         {
152             if( m_edges[i][j] != NULL )
153             {
154                 value = *(m_edges[i][j]);
155             }
156             else
157             {
158                 THROW_EXCEPTION(InvalidOperationException, "No value assigned to this edge...");
159             }
160         }
161
162         return ret;
163     }
164
165     bool setEdge(int i, int j, const E& value)
166     {
167         bool ret = ((0 <= i) && (i < vCount()) &&
168                     (0 <= j) && (j < vCount()) );
169
170         if( ret )
171         {
172             E* ne = m_edges[i][j];
173
174             if( ne == NULL )
175             {
176                 //i和j之间没有边,现在要设置一条边
177                 ne = new E();
178
179                 if( ne != NULL )
180                 {
181                     *ne = value;
182
183                     m_edges[i][j] = ne;
184
185                     m_eCount++;
186                 }
187                 else
188                 {
189                     THROW_EXCEPTION(NoEnoughMemoryException, "No memory to store new edge value...");
190                 }
191             }
192             else
193             {
194                 *ne = value;
195             }
196         }
197
198         return ret;
199     }
200
201     bool removeEdge(int i, int j)
202     {
203         bool ret = ((0 <= i) && (i < vCount()) &&
204                     (0 <= j) && (j < vCount()) );
205
206         if( ret )
207         {
208             E* toDel = m_edges[i][j];
209
210             m_edges[i][j] = NULL;
211
212             if( toDel != NULL )
213             {
214                 m_eCount--;
215
216                 delete toDel;
217             }
218         }
219
220         return ret;
221     }
222
223     int vCount()
224     {
225         return N;
226     }
227
228     int eCount()
229     {
230         return m_eCount;
231     }
232
233     int OD(int i)
234     {
235         int ret = 0;
236
237         if( (0 <= i) && (i < vCount()) )
238         {
239             for(int j = 0; j < vCount(); j++)
240             {
241                 if( m_edges[i][j] != NULL )
242                 {
243                     ret++;
244                 }
245             }
246         }
247         else
248         {
249             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
250         }
251
252         return ret;
253     }
254
255     int ID(int i)
256     {
257         int ret = 0;
258
259         if( (0 <= i) && (i < vCount()) )
260         {
261             for(int j = 0; j < vCount(); j++)
262             {
263                 if( m_edges[j][i] != NULL )
264                 {
265                     ret++;
266                 }
267             }
268         }
269         else
270         {
271             THROW_EXCEPTION(InvalidParameterException, "Index i is invalid...");
272         }
273
274         return ret;
275     }
276
277     ~MatrixGraph()
278     {
279         for(int i = 0; i < vCount(); i++)
280         {
281             for( int j = 0; j < vCount(); j++)
282             {
283                 delete m_edges[i][j];
284             }
285
286             delete m_vertexes[i];
287         }
288     }
289 };
290
291 }
292
293 #endif // MATRIXGRAPH_H

测试程序如下:

 1 #include <iostream>
 2 #include "BTreeNode.h"
 3 #include "MatrixGraph.h"
 4
 5 using namespace std;
 6 using namespace DTLib;
 7
 8
 9 int main()
10 {
11     MatrixGraph<3, int, int> g;
12
13     g.setEdge(0, 1, 1);
14     g.setEdge(1, 0, 2);
15     g.setEdge(1, 2, 3);
16
17     cout << "vCount : " << g.vCount() << endl;
18     cout << "eCount : " << g.eCount() << endl;
19     cout << "ID(1) : " << g.ID(1) << endl;
20     cout << "OD(1) : " << g.OD(1) << endl;
21     cout << "TD(1) : " << g.TD(1) << endl;
22
23     cout << "W(0, 1) : " << g.getEdge(0, 1) << endl;
24     cout << "W(1, 0) : " << g.getEdge(1, 0) << endl;
25     cout << "W(1, 2) : " << g.getEdge(1, 2) << endl;
26
27     SharedPointer< Array<int> > aj = g.getAdjacent(1); //获取1顶点的邻接顶点
28
29     cout << endl;
30     for(int i = 0; i < aj->length(); i++)
31     {
32         cout << (*aj)[i] << " ";
33     }
34
35     cout << endl;
36
37     cout << "delete edge : " << endl;
38     g.removeEdge(0, 1);
39
40     cout << "eCount : " << g.eCount() << endl;
41
42     g.setVertex(0, 100);
43
44     cout << "V(0) : " << g.getVertex(0) << endl;
45
46     cout << "W(0, 1) : " << g.getEdge(0, 1) << endl;
47     return 0;
48 }

结果如下:

小结:

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

时间: 2024-08-30 14:46:50

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

第五十二课 树的存储结构与实现

GTree是通用树结构. 每个节点都包含了指向父节点的指针. 添加GTreeNode.h文件: 1 #ifndef GTREENODE_H 2 #define GTREENODE_H 3 4 #include "TreeNode.h" 5 #include "LinkList.h" 6 7 namespace DTLib 8 { 9 10 template < typename T > 11 class GTreeNode : public TreeNo

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

增加新顶点的时候只能在链表的末尾进行,其他的顶点的编号不能打乱了. 添加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

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

广度优先相当于对顶点进行分层,层次遍历. 在Graph.h中添加BFS函数: 1 #ifndef GRAPH_H 2 #define GRAPH_H 3 4 #include "Object.h" 5 #include "SharedPointer.h" 6 #include "Array.h" 7 #include "DynamicArray.h" 8 #include "LinkQueue.h" 9 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中无邻接顶

NeHe OpenGL教程 第二十二课:凹凸映射

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第二十二课:凹凸映射 凹凸映射,多重纹理扩展: 这是一课高级教程,请确信你对基本知识已经非常了解了.这一课是基于第六课的代码的,它将建立一个非常酷的立体纹理效果. 这一课由Jens Schneider所写,它基本上是由第6课改写而来

NeHe OpenGL教程 第十二课:显示列表

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第十二课:显示列表 显示列表: 想知道如何加速你的OpenGL程序么?这一课将告诉你如何使用OpenGL的显示列表,它通过预编译OpenGL命令来加速你的程序,并可以为你省去很多重复的代码. 这次我将教你如何使用显示列表,显示列表将

【C++探索之旅】第一部分第十二课:指针一出,谁与争锋

内容简介 1.第一部分第十二课:指针一出,谁与争锋 2.第一部分第十三课预告:第一部分小测验 指针一出,谁与争锋 上一课<[C++探索之旅]第一部分第十一课:小练习,猜单词>中,我们用一个小游戏来总结了之前几课学习的知识点. 现在,终于来到第一部分的最后一个知识点了,也是C++的基础部分的最后一个讲题.之后进入第二部分,就会开始面向对象之旅.因此,这一课也注定不平凡.系好安全带吧,因为马力要加足了! 指针这个C系语言的难点(著名的C语言里也有指针),令无数英雄"尽折腰",也

第三十二课 二维数组及其定义 【项目1-2】

第三十二课  二维数组及其定义 项目一 [折腾二维数组] 创建一个5行4列的二维整型数组,通过初始化,为数组中的前两列的10个元素赋初值,然后: 通过键盘输入,使后两列的10个元素获得值: 按行序优先输出数组元素: 将所有元素值乘以3后保存在数组中: 按列序优先输出(输出的第一行是数组中的第一列--,其实输出的就是"转置"): 将数组"倒"着输出(即最后一行最后一列的最先输出,第0行第0列的最后输出): 输出数组中的所有偶数: 输出所有行列下标之和为3的倍数的元素值

NeHe OpenGL教程 第四十二课:多重视口

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第四十二课:多重视口 多重视口 画中画效果,很酷吧.使用视口它变得很简单,但渲染四次可会大大降低你的显示速度哦:) 欢迎来到充满趣味的另一课.这次我将向你展示怎样在单个窗口内显示多个视口.这些视口在窗口模式下能正确的调整大小.其中有