使用邻接矩阵实现的图结构(添加深度优先搜索)
这次我使用了深度优先搜索。以前的文章如下所示。这个算法困难啊,调试了我好一段时间。下面就是我扩充的深度优先搜索的内容。以前发布的程序有诸多不足,还有几个致命的错误,我就不解释了,这个是优化了的,比以前的好了些。我以前写的图结构:http://student.csdn.net/space.php?uid=999749&do=blog&id=51129
下面是我的JGraph.h代码:
- /*----------------------------------------------------------------------------
- 蒋轶民制作:E-mail:jiangcaiyang123@163.com
- ------------------------------------------------------------------------------
- 文件名:JGraph.h
- ------------------------------------------------------------------------------
- 作用:这是使用邻接矩阵制作的图状结构,基本实现了图的创建操作。
- ------------------------------------------------------------------------------
- 调用规范:无
- /*--------------------------------------------------------------------------*/
- // 条件编译
- #ifndef _JGRAPH_H_
- #define _JGRAPH_H_
- /*--------------------------------------------------------------------------*/
- // 头文件
- #include <limits.h>
- // 定义的宏
- #define INFINITY INT_MAX
- #define MAX_VERTEX_NUM 20
- /*--------------------------------------------------------------------------*/
- // 定义一系列类型
- enum GraphKind { DG, DN, UDG, UDN };// 图的类型枚举
- typedef unsigned int VRType;
- typedef char InfoType;
- typedef struct
- {
- VRType adj;// 顶点关系类型
- InfoType* info;// 弧的信息
- } AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
- // 图的定义
- template <typename CustomType>
- class JMatrixGraph
- {
- public:
- JMatrixGraph():vexnum(0),arcnum(0){}// 默认构造函数
- void CreateGraph( GraphKind inputKind );//创建图
- void DFSTraverse( bool (*Visit)(int v) );// 深度优先搜索遍历
- private:
- void CreateDG( void );// 创建有向图
- void CreateDN( void );// 创建有向网
- void CreateUDG( void );// 创建无向图
- void CreateUDN( void );// 创建无向网
- void DepthFirstSearch( int v, bool (*Visit)(int v) );// 深度优先搜索
- int FirstAdjVex( int v );// 返回第v个顶点的第一个邻接点
- int NextAdjVex( int v, int w );// 返回第v个顶点的下一个邻接点
- CustomType vexs[MAX_VERTEX_NUM];// 顶点向量
- AdjMatrix arcs;// 邻接矩阵
- int vexnum, arcnum;// 图的顶点数和弧数
- GraphKind kind;// 图的种类标志
- bool visited[MAX_VERTEX_NUM];// 访问标志数组
- };
- /*--------------------------------------------------------------------------*/
- //创建图
- template <typename CustomType>
- void JMatrixGraph<CustomType>::CreateGraph( GraphKind inputKind )
- {
- switch ( inputKind )
- {
- case DG: return CreateDG();
- case DN: return CreateDN();
- case UDG: return CreateUDG();
- case UDN: return CreateUDN();
- }
- }
- template <typename CustomType>// 创建有向图
- void JMatrixGraph<CustomType>::CreateDG( void )
- {
- int i, j, k;
- int v1, v2, incInfo;
- cout<<"输入顶点个数:/n";
- cin>>vexnum;
- cout<<"输入弧的个数:/n";
- cin>>arcnum;
- if ( arcnum > vexnum * ( vexnum - 1 ) * 0.5f )
- {
- cout<<"输入错误!因为不满足n(n-1)/2的条件。/n";
- return;
- }
- cout<<"输入弧的信息(0表示忽略):/n";
- cin>>incInfo;
- for ( i = 0; i < vexnum; i++ )
- {
- cout<<"请输入第"<<i+1<<"个顶点的内容:/n";
- cin>>vexs[i];
- }
- for ( i = 0; i < vexnum; i++ )
- {
- for ( j = 0; j < vexnum; j++ )
- {
- arcs[i][j].adj = 0;
- arcs[i][j].info = NULL;
- }
- }
- for ( k = 0; k < arcnum; k++ )
- {
- cout<<"请输入第"<<k+1<<"边连接的两个顶点。/n";
- cin>>v1>>v2;
- arcs[v1-1][v2-1].adj = 1;
- if ( incInfo != 0 )
- {
- cout<<"输入弧的信息,以字符串的形式存储。/n";
- cin>>arcs[v1-1][v2-1].info;
- }
- }// 这里设置断点,下同
- }
- template <typename CustomType>// 创建有向网
- void JMatrixGraph<CustomType>::CreateDN( void )
- {
- int i, j, k;
- int v1, v2, incInfo;
- int w;
- cout<<"输入顶点个数:/n";
- cin>>vexnum;
- cout<<"输入弧的个数:/n";
- cin>>arcnum;
- if ( arcnum > vexnum * ( vexnum - 1 ) * 0.5f )
- {
- cout<<"输入错误!因为不满足n(n-1)/2的条件。/n";
- return;
- }
- cout<<"输入弧的信息(0表示忽略):/n";
- cin>>incInfo;
- for ( i = 0; i < vexnum; i++ )
- {
- cout<<"请输入第"<<i+1<<"个顶点的内容:/n";
- cin>>vexs[i];
- }
- for ( i = 0; i < vexnum; i++ )
- {
- for ( j = 0; j < vexnum; j++ )
- {
- arcs[i][j].adj = INFINITY;
- arcs[i][j].info = NULL;
- }
- }
- for ( k = 0; k < arcnum; k++ )
- {
- cout<<"请输入第"<<k+1<<"边连接的两个顶点和权值。/n";
- cin>>v1>>v2>>w;
- arcs[v1-1][v2-1].adj = w;
- if ( incInfo != 0 )
- {
- cout<<"输入弧的信息,以字符串的形式存储。/n";
- cin>>arcs[v1-1][v2-1].info;
- }
- }
- }
- template <typename CustomType>// 创建无向图
- void JMatrixGraph<CustomType>::CreateUDG( void )
- {
- int i, j, k;
- int v1, v2, incInfo;
- cout<<"输入顶点个数:/n";
- cin>>vexnum;
- cout<<"输入弧的个数:/n";
- cin>>arcnum;
- if ( arcnum > vexnum * ( vexnum - 1 ) * 0.5f )
- {
- cout<<"输入错误!因为不满足n(n-1)/2的条件。/n";
- return;
- }
- cout<<"输入弧的信息(0表示忽略):/n";
- cin>>incInfo;
- for ( i = 0; i < vexnum; i++ )
- {
- cout<<"请输入第"<<i+1<<"个顶点的内容:/n";
- cin>>vexs[i];
- }
- for ( i = 0; i < vexnum; i++ )
- {
- for ( j = 0; j < vexnum; j++ )
- {
- arcs[i][j].adj = 0;
- arcs[i][j].info = NULL;
- }
- }
- for ( k = 0; k < arcnum; k++ )
- {
- cout<<"请输入第"<<k+1<<"边连接的两个顶点。/n";
- cin>>v1>>v2;
- arcs[v1-1][v2-1].adj = 1;
- cout<<"该元素的值是:"<<arcs[v1-1][v2-1].adj;
- if ( incInfo != 0 )
- {
- cout<<"输入弧的信息,以字符串的形式存储。/n";
- cin>>arcs[v1-1][v2-1].info;
- }
- arcs[v2-1][v1-1].adj = arcs[v1-1][v2-1].adj;
- }
- }
- template <typename CustomType>// 创建无向网
- void JMatrixGraph<CustomType>::CreateUDN( void )
- {
- int i, j, k;
- int v1, v2, incInfo;
- int w;
- cout<<"输入顶点个数:/n";
- cin>>vexnum;
- cout<<"输入弧的个数:/n";
- cin>>arcnum;
- if ( arcnum > vexnum * ( vexnum - 1 ) * 0.5f )
- {
- cout<<"输入错误!因为不满足n(n-1)/2的条件。/n";
- return;
- }
- cout<<"输入弧的信息(0表示忽略):/n";
- cin>>incInfo;
- for ( i = 0; i < vexnum; i++ )
- {
- cout<<"请输入第"<<i+1<<"个顶点的内容:/n";
- cin>>vexs[i];
- }
- for ( i = 0; i < vexnum; i++ )
- {
- for ( j = 0; j < vexnum; j++ )
- {
- arcs[i][j].adj = INFINITY;
- arcs[i][j].info = NULL;
- }
- }
- for ( k = 0; k < arcnum; k++ )
- {
- cout<<"请输入第"<<k+1<<"边连接的两个顶点和权值。/n";
- cin>>v1>>v2>>w;
- arcs[v1-1][v2-1].adj = w;
- if ( incInfo != 0 )
- {
- cout<<"输入弧的信息,以字符串的形式存储。/n";
- cin>>arcs[v1-1][v2-1].info;
- }
- arcs[v2-1][v1-1].adj = arcs[v1-1][v2-1].adj;
- }
- }
- /*--------------------------------------------------------------------------*/
- // 深度优先搜索遍历
- template <typename CustomType>
- void JMatrixGraph<CustomType>::DFSTraverse( bool (*Visit)(int v) )
- {
- int v;
- for ( v = 0; v < vexnum; v++ ) visited[v] = false;
- for ( v = 0; v < vexnum; v++ )
- if ( !visited[v] ) DepthFirstSearch( v, Visit );
- }
- /*--------------------------------------------------------------------------*/
- // 深度优先搜索
- template <typename CustomType>
- void JMatrixGraph<CustomType>::DepthFirstSearch( int v, bool (*Visit)(int v) )
- {
- visited[v] = true; Visit( v );
- int w;
- for ( w = FirstAdjVex( v ); w >= 0; w = NextAdjVex( v, w ) )
- if ( !visited[w] ) DepthFirstSearch( w, Visit );
- }
- /*--------------------------------------------------------------------------*/
- // 返回第v个顶点的第一个邻接点
- template <typename CustomType>
- int JMatrixGraph<CustomType>::FirstAdjVex( int v )
- {
- int i;
- for ( i = 0; i < vexnum; i++ )
- if ( arcs[v][i].adj != 0 ) return i;// 这里只对无向图进行计算
- return -1;
- }
- /*--------------------------------------------------------------------------*/
- // 返回第v个顶点的下一个邻接点
- template <typename CustomType>
- int JMatrixGraph<CustomType>::NextAdjVex( int v, int w )
- {
- int i;
- for ( i = w + 1; i < vexnum; i++ )
- if ( arcs[v][i].adj != 0 ) return i;// 这里只对无向图进行计算
- return -1;
- }
- #endif
下面是我对《数据结构(严蔚敏版)》168页的G4图进行深度优先搜索。MainFrame.h文件如图所示。
- /*----------------------------------------------------------------------------
- 蒋轶民制作:E-mail:jiangcaiyang123@163.com
- ------------------------------------------------------------------------------
- 文件名:MainFrame.h
- ------------------------------------------------------------------------------
- 作用:验证图结构是否创建成功。
- /*--------------------------------------------------------------------------*/
- // 头文件
- #include <iostream>
- #include "JGraph.h"
- using namespace std;
- bool VisitFunc( int v )
- {
- cout<<"-----------深度优先搜索------------/n";
- cout<<"访问第"<<v+1<<"个顶点/n";
- return true;
- }
- // 程序的入口
- int main( int argc, char** argv )
- {
- JMatrixGraph<char> jmg;
- jmg.CreateGraph( UDG );
- jmg.DFSTraverse( VisitFunc );
- return 0;
- }
程序的截图如图所示:
以后还会实现广度优先搜索和更多的功能的!