数据结构 - 图

图的定义

图的定义大体上有以下两种方式。

二元组的定义

      图G是一个二元组(V,E),其中V称为顶点集,E称为边集。它们亦可写成V(G)和E(G)。E的元素是一个二元组数对,用(x,y)表示,其中x,y∈V。

三元组的定义

      一个,是指一个三元组(V,E,I),其中V称为顶集(Vertices set),E称为边集(Edges set),E与V不相交;I称为关联函数,I将E中的每一个元素映射到VxV。如果I(e)=(u,v)(e∈E;u,v∈V),那么称边e连接顶点u,v,而u,v则称作e的端点,u,v此时关于e相邻。同时,若两条边i,j有一个公共顶点u,则称i,j关于u相邻。

图的遍历

图的遍历方式有两种,分别是深度优先遍历和广度优先遍历。

      图的深度优先遍历是树的先序遍历的推广,它的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi进行访问,再从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则退回到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点w,从w出发按照同样的方法进行遍历,直到图中所有顶点都被访问。

Boolean visited[MAX_VERTEX_NUM]; //访问标志数组。
Status (*VisitFunc)(int v); //VisitFunc是访问函数,对图的每个顶点调用该函数。

void DFSTraverse (Graph G, Status(*Visit)(int v)) //图的深度优先遍历。
{
    VisitFunc = Visit;
    for(v=0; v<G.vexnum; ++v)
        visited[v] = FALSE; //访问标志数组初始化。
    for(v=0; v<G.vexnum; ++v)
        if(!visited[v])
            DFS(G, v); //对尚未访问的顶点调用DFS。
}

void DFS(Graph G, int v) //从第v个顶点出发递归地深度优先遍历图G。
{
    visited[v]=TRUE;
    VisitFunc(v); //访问第v个顶点。
    for(w=FirstAdjVex(G,v); w>=0; w=NextAdjVex(G,v,w))
    //FirstAdjVex返回v的第一个邻接顶点,若顶点在G中没有邻接顶点,则返回空(0)。
    //若w是v的邻接顶点,NextAdjVex返回v的(相对于w的)下一个邻接顶点。
    //若w是v的最后一个邻接点,则返回空(0)。
        if(!visited[w])
            DFS(G, w); //对v的尚未访问的邻接顶点w调用DFS。
}

      图的广度优先遍历是树的按层次遍历的推广,它的基本思想是:首先访问初始点vi,并将其标记为已访问过。接着访问vi的所有未被访问过的邻接点vi1,vi2,...,vit,并均标记为已访问过。然后再按照vi1,vi2,...,vit的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过。依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问。

扫描二维码关注公众号,回复: 4502145 查看本文章
Boolean visited[MAX_VERTEX_NUM]; //访问标志数组。
Status (*VisitFunc)(int v); //VisitFunc是访问函数,对图的每个顶点调用该函数。

void BFSTraverse (Graph G, Status(*Visit)(int v)) //图的广度优先遍历。
{
    VisitFunc = Visit;
    for(v=0; v<G.vexnum, ++v)
        visited[v] = FALSE;
    initQueue(Q); //置空辅助队列Q。
    for(v=0; v<G.vexnum; ++v)
        if(!visited[v])
        {
            visited[v]=TRUE;
            VisitFunc(v);
            EnQueue(Q, v); //v入队列
            while(!QueueEmpty(Q))
            {
                DeQueue(Q, u); //队首元素出队并置为u。
                for(w=FirstAdjVex(G,u); w>=0; w=NextAdjVex(G,u,w))
                    if(!Visited[w]) //w为u的尚未访问的邻接顶点。
                    {
                        Visited[w]=TRUE;
                        VisitFunc(w);
                        EnQueue(Q, w);
                    }
            }
        }
}

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

猜你喜欢

转载自www.cnblogs.com/kwincaq/p/10118653.html