采用邻接矩阵输出无向图的深度和广度遍历

 代码如下:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define MVNum 100
#define MaxInt 32767
typedef char VerType;
typedef int ArcType;
//图的存储结构
int visited[MVNum];
typedef struct
{
    VerType vexs[MVNum];//顶点表
    ArcType arcs[MVNum][MVNum];//邻接矩阵
    ArcType vexnum,arcnum;//图的当顶点数和边数
}AMGraph;//Adjacency Matrix Graph
//链队的存储结构
typedef struct StackNode
{
    ArcType data;
    struct StackNode *next;
}StackNode,*LinkStack;

typedef struct QNode
{
    ArcType data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
    QueuePtr front;//对头指针
    QueuePtr rear;//队尾指针
}LinkQueue;


//链队的初始化
int InitQueue(LinkQueue &Q)
{//构造一个空队列
    Q.front=Q.rear=new QNode;
    Q.front->next=NULL;
    return 0;
}

//链队的入队
int EnQueue(LinkQueue &Q,int e)
{//插入元素e为新的队尾元素
    QueuePtr p;
    p=new QNode;
    p->data=e;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;
    return 0;
}

//链队的出队
int DeQueue(LinkQueue &Q,int &e)
{
    QueuePtr p;
    if(Q.front==Q.rear) return 1;
    p=Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)
        Q.rear=Q.front;
        delete p;
    return 0;
}

//判断链队是否为空
int QueueEmpty(LinkQueue Q)
{
        return Q.front==Q.rear;
}

//在图中查找顶点(邻接矩阵)
ArcType LocateVex1(AMGraph &G,ArcType u)
{
    for(ArcType i=0;i<G.vexnum;i++)
    {
        if(u==G.vexs[i])
            return i;

    }
    return -1;
}

//采用邻接矩阵创建无向图
ArcType CreateUDM2(AMGraph &G)
{
    ArcType v1,v2,w;
    printf("请输入总顶点数、总边数:\n");
    scanf("%d %d",&G.vexnum,&G.arcnum);
    printf("请输入顶点信息:\n");
    for(ArcType i=0;i<G.vexnum;i++)//依次输入顶点信息
    {
        scanf("%d",&G.vexs[i]);
    }
    for(ArcType i=0;i<G.vexnum;i++)
        {
            for(ArcType j=0;j<G.vexnum;j++)
            {
                G.arcs[i][j]=0;//初始化邻接矩阵,边的权值均置为0
            }
        }
    for(ArcType k=0;k<G.arcnum;k++)//构造邻接矩阵
    {
        printf("请输入一条边依附的两个顶点:\n");
        scanf("%d %d",&v1,&v2);
        ArcType i=LocateVex1(G,v1);ArcType j=LocateVex1(G,v2);
        G.arcs[i][j]=1;
        G.arcs[j][i]=G.arcs[i][j];
    }
    return 0;
}

//输出邻接矩阵
ArcType Printf(AMGraph &G)
{
    for(ArcType i=0;i<G.vexnum;i++)
    {
         for(ArcType j=0;j<G.vexnum;j++)
        {
            printf("%6d",G.arcs[i][j]);
        }
        printf("\n");
    }
}

int FirstAdjVex(AMGraph G,int v)
{
	for(int i=0;i<G.vexnum;i++)
    {
		if(G.arcs[v][i]!=0&&visited[i]==0)
		return i;
	}
	return -1;
}
int NextAdjVex(AMGraph G,int v,int w)
{
	for(int i=w;i<G.vexnum;i++)
    {
		if(G.arcs[v][i]!=0&&visited[i]==0)
		return i;
	}
	return -1;
}

//邻接矩阵的深度优先递归算法
void DFS(AMGraph G,ArcType v)
{
    ArcType w;
    printf("%d ",G.vexs[v]);//访问第v个顶点
    visited[v]=1;//访问之后,将辅助数组visited[v]将0置为1
    for(w=0;w<G.vexnum;w++)
    {
        if((G.arcs[v][w]!=0)&&(!visited[w]))//G.arcs[v][w]!=0且visited[w]数组不为0时(为0时代表visited[w]已经被访问过了)
            DFS(G,w);//G.arcs[v][w]!=0表示w是v的邻接点,如果w未访问,则递归调用DFS
    }
}

//邻接矩阵的广度优先遍历
ArcType BFS(AMGraph G,ArcType v)
{
    LinkQueue Q;
    ArcType u,w;
    printf("%d ",G.vexs[v]);
    visited[v]=1;//置访问标志数组相应分量值为1
    InitQueue(Q);//辅助队列Q初始化,置空
    EnQueue(Q,v);//v进栈
    while(!QueueEmpty(Q))//当队列非空时,执行下面的语句
    {
        DeQueue(Q,u);//对头元素出队并置为u
        for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
            //依次检查u的所有邻接点w,FirstAdjVex(G,u)表示u的第一个邻接点
            //NestAdjVex(G,u,w)表示u相对于w的下一个邻接点,w>=0表示存在邻接点
        {
            if(!visited[w])//w为u的尚未访问的邻接顶点
            {
                printf("%d ",G.vexs[w]);//访问w
                visited[w]=1;//置访问标志数组相应分量值为1
                EnQueue(Q,w);//w进队
            }//if
        }//for
    }//while
}//BFS

ArcType main()
{
    AMGraph G;
    int w=0;
    CreateUDM2(G);//用邻接矩阵创建无向图
    printf("输出无向图的邻接矩阵\n");
    Printf(G);//输出无向图的邻接矩阵
    printf("深度优先遍历的结果为:\n");
    DFS(G,w);
    printf("\n");
    printf("广度优先遍历的结果为:\n");
    for(int i=0;i<MVNum;i++)
    visited[i]=0;//没有访问之前,visited[v]数组置为0
    BFS(G,w);
    return 0;
}

创建的无向图如下:

 

 运行结果如下:

 

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值