图的深度优先遍历和广度优先遍历
程序员文章站
2022-05-21 21:05:02
...
最近几天在复习数据结构的考试,也算是一个查缺补漏的过程,所以手写代码记录一下.另外因为c/c++类中实参与形参最好不能重名的问题,困扰了许久,也是醉了.
函数指针void (*visit)可以接收一个函数名,将函数作为参数,类似于python里的函数式编程.
指针函数int *visit的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。
下面记录一下,在c/c++中,成员函数与成员形参不能同名,
class A
{
private:
int a;
public:
A(int a){a=a;} //该方法不行,形参a的作用域将覆盖成员变量的作用域,所以成员变量a不会被赋值
}
接下来是图的两种遍历方法
第一种是DFS(深度优先遍历),采用递归的方式从一个顶点不断访问他的最近的邻接顶点,直到末端再返回到有其他其他邻接点的顶点处进行递归
template<class T>
void AdjListUndirGraph<T>::DFS(int v,void (*(visit)(const T &e)))const
{
SetTag(v,true);
T e;
GetElem(v,e);
(*visit)(e);
for(int w=FirstAdjVex(v);w>=0;w=NextAdjVex(v,w))
if(!GetTag(w))
DFS(w);
}
template<class T>
void AdjListUndirGraph<T>::DFSTraverse(void (*(visit)(const T &e)))const
{
int v;
for(v=0;v<GetVexNum();v++)
SetTag(v,false);
for(v=0;v<GetVexNum();v++)
if(!GetTag(v))
DFS(v,visit);
}
第二种是BFS(广度优先遍历),将一个顶点的所有邻接顶点入队访问,再依次出队,接着继续将邻接顶点的邻接顶点入队,再依次出队,不断重复,直到访问结束.
template<class T>
void AdjListDirGraph<T>::BFS(int v,void (*visit)(const T &e))const
{
SetTag(v,true);
T e;
GetElem(v,e);
(*visit)(e);
LinkQueue q;
q.InQueue(v);
while(!q.Empty())
{
int u,w;
q.OutQueue(u);
for(w=FirstAdjVex(u);w>=0;w=NextAdjVex(u,w))
if(!GetTag(w))
{
SetTag(w,true);
GetElem(w,e);
(*visit)(e);
q.InQueue(w);
}
}
template<class T>
void AdjListDirGraph<T>::BFSTraverse(void (*visit)(const T &e))const
{
int v;
for(v=0;v<GetVexNum;v++)
SetTag(v,false);
for(v=0;v<GetVexNum;v++)
if(!GetTag(v))
BFS(v,visit);
}
上一篇: Shell脚本报错unary operator expected
下一篇: 遇到奇葩人怎么办