28图结构的类实现
图结构的类实现示例
说明:以无向图为例,给出图类、先深搜索和拓扑排序的类实现
1.邻接表存储的图类
(1)有关类型定义
typedef char Vname_type; //顶点名类型,假定字符型
typedef int Vdata_type; //顶点所带信息类型,假定整型
typedef float cost_type; //边的权类型,假定实型
typedef int graph_type; //图带有的信息类型,假定整型
(2)边结点类
class edge_node
{
public:
int adjacent; //邻接点编号
edge_node *next; //指向下一个边结点的指针
cost_type cost; //边的耗费(对于加权图)
edge_node(int n, cost_type t1=0, edge_node *t2=NULL)
{cost=t1; next=t2; adjacent=n;} //结点初始化的构造函数
};
(3)表头结点类
class Linklist
{
public:
Vname_type name;//顶点名称,用于由顶点序号查找顶点名称
edge_node *firstedge; //邻接表首指针
//若是有向图,域名可改为fistarc
Linklist(){ firstedge=NULL;}
…… //他成员函数
};
(4)顶点对应的存储结点类
class Vnode
{
public:
Vname_type name; //顶点名称
int number; //顶点的编号,可以由顶点名查找顶点编号
Vdata_type data; //顶点所带的信息
//获取顶点信息的成员函数可以加在此处
};
(5)图的模板类
template <int n> //n是顶点的个数
class graph
{ Vnode V[n]; //存储图的顶点集
Linklist L[n]; //图的邻接表
graph_type gdata; //图本身所带信息
public:
void creat_graph(); //构造图的邻接表
…… //其他的成员函数
};
2.先深搜索算法的类实现
(1)graph类进一步具体化
template <int n> //n是顶点的个数
class graph
{ Vnode V[n];
Linklist L[n];
graph_type gdata;
void dfs(int v, int mark[]);
public:
void creat_graph( ); //构造图的邻接表
void dfs_main(); //先深搜索函数
}
(2)成员函数的实现
template <int n>
void graph<n>::creat_graph( ) //构造邻接表
{ … //略 }
template <int n>
void graph<n>::dfsmain( ) //先深搜索的主控函数
{ int v;
int mark[n]; //顶点访问否标记
for(v=0;v<n;v++)mark[v]=0; //对所有顶点作未访问标记
for(v=0;v<n;v++)
if(mark[v]==0) dfs(v,mark); //若存在未访问顶点v,则以v为搜索起点
}
template <int n> void graph<n>::dfs(int v, int mark[]) //搜索函数
{ edge_node *p; int w; //p是边结点指针,w是邻接点编号
visit(v); //访问v,具体访问操作从略
mark[v]=1; //置已访问标记
p=L[v].firstedge; //p指向v的邻接表首结点
while(p)
{ w=p->adjacent; //w是v的邻接点
if(mark[w]==0)dfs(w,mark);
p=p->next;
}
}(3)用法示例
假设图中有10个顶点,则可以定义:
graph<10> g10;
此后,用语句:
g10.creat_graph( );
和
g10.dfs_main();
输入图的边集,产生邻接表,并完成。
3.拓扑排序算法的类实现
在类graph的定义中添加用于拓扑排序的函数
template<int n>
int graph<n>::topological_sort( )
{ int v, count=0; //count输出顶点个数的计数器
…; //其他局部量定义部分
置stack为空; //stack是入度为0的顶点栈
for(v=0;v<n;v++) //n是顶点数
if(L[v].indegree==0)将v推入栈stack中;
while(stack不空)
{
从栈stack弹出一个顶点v;
输出v; count++; //输出,并计数
p=L[v].firstarc;
while(p!=NULL)
{ w=p->adjvex; //<v,w>是一条边
L[w].indegree--;
if(L[w].indegree==0)将w推入栈stack中;
p=p->next;
}
} if(count<n) return 1; //图中有回路
else return 0; //图中没有回路
}