图的应用

之前写了图的基本概念,现在写图的一般应用。
一.寻找一条路径
用广度优先搜索,虽然能很好的找到能到达的所有点,但是却不容易找到路径,而深度优先搜索里面隐含了路径,所以寻找路径一般用深度优先搜索。

bool rFindPath(int s)
{//寻找路径的实际算法。从顶点s开始实施深度优先搜索
//顶点s不应该等于终点
//当且仅当一条路径找到了,返回true
reach[s]=1;//标记起始点
vertexIterator<T>* is=iterator(s);//以s为起点的迭代器
int u;
while((u=is->next())!=0)//当s存在邻接点时
{//访问s的一个邻接顶点
if(reach[u]==0)//u是一个没有到达的顶点
{//移到顶点u
path[++length]=u;//不管对不对先加入到路径中,不对再删除
if(u==destination||rFindPath(u))
    return true;
//从顶点u到终点没有路径
length--;//从路径中删除u

}

}
delete is;
return false;   
}

这是一个迭代算法,使用了深度优先搜索的方法,定义一条路径数组,我们将算法寻找的点全部点插入路径数组,如果最后一个点是目标点则结束算法,不然上退一格删除上一个插入的点,然后从上退的那个点开始重新寻找路径。

int *findPath(int theSource,int theDestination)
{
    int n=numberOfVertices();
    path=new int[n+1];
    path[1]=theSource;//第一个顶点总是
    length=1;//当前路径长度+1
    destination=theDestination;
    reach=new int [n+1];
    for(int i=1;i<=n;i++)
        reach[i]=0;
    if(theSource==theDestination||rFindPath(theSource))
        //找到一条路径
    path[0]=length-1;//index 0里面存取路径长度
    else
    {
        delete [] path;
        path=NULL;
    }
    delete [] reach;
    return path;

}

上述代码为寻找路径的前序代码,主要作用是定义变量数组和调用rfindPath函数。代码只是能寻找到一条路径但不保证是最短路径。

二.检查一个图是否是连通的
以下代码确定一个无向图是否连通。

bool connected()
{//当且仅当图连通时,返回true
//确定这是一个无向图
if(directed())
    throw undefinedMethod("graph::connected() not defined for directed graphs");
int n=numberOfVertices();
reach=new int [n+1];//默认reach[i]=0
dfs(1,reach,1);
//检查是否所有顶点都已经标记
for(int i=1;i<=n;i++)
if(reach[i]==0)
return false;
return true;    
}

原理很简单,就是判断起始点与任意其他点之间是否有一条路径。

以下代码解决构建标记问题(就是确定一个图有一个连通区域)

int labelComponents(int c[])
{
    //给无向图的构建做标记
    //返回构建的个数
    //令c[i]是顶点i的构件号
    //确定是一个无向图
    if(directed())
    throw undefinedMethod("graph::connected() not defined for directed graphs");
int n=numberOfVertices();
//令所有顶点是非构件
for(int i=1;i<=n;i++)
    c[i]=0;
label=0;//初始化标记为0
for(int i=1;i<=n;i++)
    if(c[i]==0)//顶点i未到达
    {//顶点i是一个新构件
    label++;
    bfs(i,c,label);//给新构件做标记

    }
    return label;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值