6-1 邻接矩阵存储图的深度优先遍历 (20 分)

  • Post author:
  • Post category:其他


6-1 邻接矩阵存储图的深度优先遍历 (20 分)

试实现邻接矩阵存储图的深度优先遍历。

函数接口定义:

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );

其中MGraph是邻接矩阵存储的图,定义如下:

typedef struct GNode

PtrToGNode;

struct GNode{


int Nv; /

顶点数

/

int Ne; /

边数

/

WeightType G[MaxVertexNum][MaxVertexNum]; /

邻接矩阵

/

};

typedef PtrToGNode MGraph; /

以邻接矩阵存储的图类型 */

函数DFS应从第V个顶点出发递归地深度优先遍历图Graph,遍历时用裁判定义的函数Visit访问每个顶点。当访问邻接点时,要求按序号递增的顺序。题目保证V是图中的合法顶点。

裁判测试程序样例:

#include <stdio.h>

typedef enum {false, true} bool;

#define MaxVertexNum 10 /* 最大顶点数设为10

/

#define INFINITY 65535 /

∞设为双字节无符号整数的最大值65535*/

typedef int Vertex; /* 用顶点下标表示顶点,为整型

/

typedef int WeightType; /

边的权值设为整型 */

typedef struct GNode

PtrToGNode;

struct GNode{


int Nv; /

顶点数

/

int Ne; /

边数

/

WeightType G[MaxVertexNum][MaxVertexNum]; /

邻接矩阵

/

};

typedef PtrToGNode MGraph; /

以邻接矩阵存储的图类型

/

bool Visited[MaxVertexNum]; /

顶点的访问标记 */

MGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */

void Visit( Vertex V )

{


printf(” %d”, V);

}

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );

int main()

{


MGraph G;

Vertex V;

G = CreateGraph();
scanf("%d", &V);
printf("DFS from %d:", V);
DFS(G, V, Visit);

return 0;

}

/* 你的代码将被嵌在这里 */

输入样例:给定图如下

在这里插入图片描述

5

输出样例:

DFS from 5: 5 1 3 0 2 4 6

这道题其实实现起来很简单,只要用一个递归就可以了

void DFS(MGraph T,Vertex V,void (*Visit)(Vertex))//这里调用了一个Visit函数输出,虽然我也不太明白为什么
{
    Visit(V);//输出
    Visited[V]=true;//改标记
    int i;
    for(i=0;i<T->Nv;i++)//邻接表遍历所有结点
    {
        if(T->G[V][i]==1&&Visited[i]==false)//找到一个邻接点递归遍历
            DFS(T,i,Visit);
    }
}

完整代码

#include<stdio.h>
typedef enum{false,true}bool;
#define MaxVertexNum 10//最大顶点数为10
#define INFINITY 65535
typedef int Vertex;//定义顶点类型
typedef int WeightType;//定义边类型

typedef struct GNode*PtrToGNode;
struct GNode{
int Nv;
int Ne;
WeightType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;
bool Visited[MaxVertexNum];

MGraph CreateGraph();
MGraph CreateGraph()
{
    MGraph T;
    T=(MGraph)malloc(sizeof(struct GNode));
    T->Nv=7;
    T->Ne=9;
    int i,j,k;
    for(i=0;i<T->Nv;i++)//先初始化再输入
        for(i=0;i<T->Nv;i++)
        T->G[i][j]=0;
        for(k=0;k<T->Ne;k++)
        {
            scanf("%d %d",&i,&j);
            T->G[i][j]=1;
            T->G[j][i]=1;
        }
        for(i=0;i<T->Nv;i++)
            Visited[i]=false;
            return T;
}
void visit(Vertex V);
void visit(Vertex V)
{
    printf(" %d",V);
}
void DFS(MGraph T,Vertex V,void (*Visit)(Vertex));
void DFS(MGraph T,Vertex V,void (*Visit)(Vertex))
{
    Visit(V);
    Visited[V]=true;
    int i;
    for(i=0;i<T->Nv;i++)
    {
        if(T->G[V][i]==1&&Visited[i]==false)
            DFS(T,i,Visit);
    }
}
int main()
{
    MGraph G;
    Vertex V;
    G=CreateGraph();
    scanf("%d",&V);
    printf("DFS from %d:",V);
    DFS(G,V,visit);
    return 0;
}

书上的深度遍历有两种

(1)

#define MaxVerNum
int flag[MaxVerNum]={0};
void DFSTraverse(Graph*G,int v)
{
Visited(v);flag[v]=1;
for(w=FirstAdfVex(G,v);w;w=NextAdjVex(G,v,w))
if(!flag[w])
DFSTraverse(G,w);
}

用邻接矩阵存储的图的两个函数实现

int firstadj(G,v)
{int w;
for(w=1;w<=G.VerNum;w++)
{if(G.AdjMatruux[v][w]>=1&&G.AdjMatrix[v][w]<INF)
{
return w;
{
}
return 0;
}
int nextadj(G,v,w)
{int i;
for(i=w+1;i<=G.VerNum;i++)
{
if(G.AdjMatrix[v][i]>=1&&G.AdjMatrix[v][i]<INF)
return i;
}
return 0;
}

用邻接表实现

int FirstAdj(VNode G[],int v)
{if(G[v].firstarc!=NULL)
return (G[v].firstarc)->adjvex;
return -1;
int NextAdj(VNode G[],int v)
{
ArcNode*p;
p=G[v].firstarc;
while(p!=NULL)
{if(visited[p-adjvex])p=p->next;
else
return p->adjvex;
}
return -1;

还有我自己写的一个NextAdj(VNode G[],int v,int w)函数

int NextAdj(VNode G[],int v,int w)
{ArcNode*p;
p=G[v].firstarc;
while(p->adjvex!=w)//先到达w的位置
p=p->next;
if(p->next==NULL)return -1;
else p=p->next;//从w的下一条边开始
while(p!=NULL)
{if(visited[p->adjvex])p=p->next;
else return p->adjvex;
}
return -1;

书上的确切过程,用邻接表实现的

#define MaxVerNum
int flag[MaxVerNum]={0}
void DFSAL(Graph*G,int i)
{
EdgeNode *p;
Visited(G->AdjList[i].vertex);
flag[i]=1;
p=G->AdjList[i].firstedge;
while(p)
{j=p->adjvex;
if(!flag[j])
DFSAL(G,j);
p=p->next;
}
}
void DFSTraverseAL(Graph*G)//图中有几个连通分量,通过该函数就会调用几次DFS函数
{int i;
for(i=0;i<G->vnum;i++)
if(!flag[i])DFS(G,i);
}



版权声明:本文为muzir_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。