实验14 TYJ图的遍历(深度和广度优先)

实验14 TYJ图的遍历(深度和广度优先)

第1关:图的深度优先和广度优先遍历

任务描述
本关任务:编写一个程序完成图的邻接矩阵到邻接表的转换,对邻接表存储的图进行递归和非递归深度优先以及广度优先遍历。

相关知识
为了完成本关任务,你需要掌握:1.广度优先算法,2.深度优先递归算法和非递归算法 3.顺序栈的操作,4.顺序队列的操作。

测试说明
平台会对你编写的代码进行测试:

测试输入:测试数据已在代码中提供;
预期输出:

图G的邻接矩阵:
  0  5  0  7  0  0
  0  0  4  0  0  0`
  8  0  0  0  0  9
  0  0  5  0  0  6
  0  0  0  5  0  0
  3  0  0  0  1  0
图G的邻接表:
  0:   1  3
  1:   2
  2:   0  5
  3:   2  5
  4:   3
  5:   0  4
从顶点0开始的DFS(递归算法):
  0  1  2  5  4  3
从顶点0开始的DFS(非递归算法):
  0  1  2  5  4  3
从顶点0开始的BFS(递归算法):
  0  1  3  2  5  4

```

开始你的任务吧,祝你成功!


#include <stdio.h>
#include <malloc.h>
#define	MAXV 100				/*最大顶点个数*/
#define	INF 32767
typedef int InfoType;
/*以下定义邻接矩阵类型*/
typedef struct 
{  	int no;						/*顶点编号*/
	InfoType info;				/*顶点其他信息*/
} VertexType;					/*顶点类型*/
typedef struct  				/*图的定义*/
{  	int edges[MAXV][MAXV]; 		/*邻接矩阵*/
   	int vexnum,arcnum;   		/*顶点数,弧数*/
	VertexType vexs[MAXV];		/*存放顶点信息*/
} MGraph;						/*图的邻接矩阵类型*/


/*以下定义邻接表类型*/
typedef struct ANode           	/*弧的结点结构类型*/
{	int adjvex;              	/*该弧的终点位置*/
   	struct ANode *nextarc; 		/*指向下一条弧的指针*/
   	InfoType info;           	/*该弧的相关信息,这里用于存放权值*/
} ArcNode;
typedef int Vertex;
typedef struct Vnode      		/*邻接表头结点的类型*/
{	Vertex data;            	/*顶点信息*/
    ArcNode *firstarc;     		/*指向第一条弧*/
} VNode;
typedef VNode AdjList[MAXV];	/*AdjList是邻接表类型    */
typedef struct 
{	AdjList adjlist;         	/*邻接表VNode adjlist[MAXV]*/
    int n,e;                 	/*图中顶点数n和边数e*/
} ALGraph;                   	/*图的邻接表类型*/

int visited[MAXV];						/*全局数组*/

 void MatToList(MGraph g,ALGraph* G);	/*邻接矩阵转换为邻接表*/
 void DispMat(MGraph g);				/*输出邻接矩阵*/
 void DispAdj(ALGraph *G);				/*输出邻接表*/
 void DFS(ALGraph *G,int v);			/*深度优先遍历邻接表*/
 void DFS1(ALGraph *G,int v);			/*非递归深度优先遍历邻接表*/
 void BFS(ALGraph *G,int v);			/*广度优先遍历邻接表*/
 
 
int main()
{
	int i,j;
	MGraph g;
	ALGraph *G;
	int A[MAXV][6]={
		{0,5,0,7,0,0},
		{0,0,4,0,0,0},
		{8,0,0,0,0,9},
		{0,0,5,0,0,6},
		{0,0,0,5,0,0},
		{3,0,0,0,1,0}};
	g.vexnum=6;g.arcnum=10;
	for (i=0;i<g.vexnum;i++)		/*建立图的邻接矩阵*/
		for (j=0;j<g.vexnum;j++)
			g.edges[i][j]=A[i][j];	
    printf("图G的邻接矩阵:\n");
    DispMat(g);
	
	G=(ALGraph *)malloc(sizeof(ALGraph));
	MatToList(g,G);					/*图G的邻接矩阵转换成邻接表*/
	printf("图G的邻接表:\n");
	DispAdj(G);
	
	printf("从顶点0开始的DFS(递归算法):\n");
	DFS(G,0);
	printf("\n");
	
	printf("从顶点0开始的DFS(非递归算法):\n");
	DFS1(G,0);
	
	printf("从顶点0开始的BFS(递归算法):\n");
	BFS(G,0);printf("\n");
}



void MatToList(MGraph g,ALGraph* G)
/*将邻接矩阵g转换成邻接表G*/
{
	int i,j,n=g.vexnum;					/*n为顶点数*/
	ArcNode *p;
	for (i=0;i<n;i++)					/*给邻接表中所有头结点的指针域置初值*/
		G->adjlist[i].firstarc=NULL;
	for (i=0;i<n;i++)					/*检查邻接矩阵中每个元素*/
		for (j=n-1;j>=0;j--)
			if (g.edges[i][j]!=0)				/*邻接矩阵的当前元素不为0*/
			{  
			/*************Begin1********************/
p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p
                p->adjvex=j;
                p->info=g.edges[i][j];
                p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p
                G->adjlist[i].firstarc=p;


			/*************End1********************/	
			}
	G->n=n;G->e=g.arcnum;
}


void DispMat(MGraph g)
/*输出邻接矩阵g*/
{
	int i,j;
	for (i=0;i<g.vexnum;i++)
	{
		for (j=0;j<g.vexnum;j++)
			if (g.edges[i][j]==INF)
				printf("%3s","∞");
			else
				printf("%3d",g.edges[i][j]);
		printf("\n");
	}
}

void DispAdj(ALGraph *G)
/*输出邻接表G*/
{
	int i;
	ArcNode *p;
	for (i=0;i<G->n;i++)
	{
		p=G->adjlist[i].firstarc;
		if (p!=NULL) printf("%3d: ",i);
		while (p!=NULL)
		{
			printf("%3d",p->adjvex);
			p=p->nextarc;
		}
		printf("\n");
	}
}



void DFS(ALGraph *G,int v) 
{
	ArcNode *p;
	visited[v]=1;                   	/*置已访问标记*/
	printf("%3d",v); 					/*输出被访问顶点的编号*/
	p=G->adjlist[v].firstarc;      		/*p指向顶点v的第一条弧的弧头结点*/
	while (p!=NULL) 
	{	
		
		/*************Begin2********************/
   if(visited[p->adjvex]==0)
DFS(G,p->adjvex);
		/*************End2********************/	
		p=p->nextarc;
	}
}
void DFS1(ALGraph *G,int v)
{
	int i,visited[MAXV];
	int St[MAXV],top=-1;//定义顺序栈并初始化栈顶指针
	ArcNode *p;
    for (i=0;i<G->n;i++) 
		visited[i]=0;				/*结点访问标志均置成0*/
    printf("%3d",v);				/*访问顶点v*/
	top++;							/*v入栈*/
	St[top]=v;
	visited[v]=1;
	while (top>=-1)					/*栈不空时循环*/
	{
		
		/*************Begin3********************/
   v=St[top];top--;
p=G->adjlist[v].firstarc;
		/*************End3********************/	
		
        while (p!=NULL && visited[p->adjvex]==1)
    		   p=p->nextarc;
        if (p==NULL)				/*若没有退到前一个*/
			top--;
		else						/*若有,选择一个*/
		{
		/*************Begin4********************/
   v=p->adjvex;
 printf("%3d",v);
 visited[v]=1;
 top++;
 St[top]=v;
		/*************End4********************/		
			
		}
	}
	printf("\n");
}   
void BFS(ALGraph *G,int v)  
{
	ArcNode *p;
	int queue[MAXV],front=0,rear=0;			/*定义循环队列并初始化*/
	int visited[MAXV];            			/*定义存放结点的访问标志的数组*/
	int w,i;
	for (i=0;i<G->n;i++) visited[i]=0;		/*访问标志数组初始化*/
	printf("%3d",v); 						/*输出被访问顶点的编号*/
	visited[v]=1;              				/*置已访问标记*/
	rear=(rear+1)%MAXV;
	queue[rear]=v;             				/*v进队*/
	while (front!=rear)       				/*若队列不空时循环*/
	{	
		/*************Begin5********************/
front=(front+1)%MAXV;
        w=queue[front];             //出队并赋给w
        p=G->adjlist[w].firstarc;

		/*************End5********************/	
		
		while (p!=NULL) 
		{	
		/*************Begin6********************/
 if (visited[p->adjvex]==0)
            {
                printf("%3d",p->adjvex); //访问之
                visited[p->adjvex]=1;
                rear=(rear+1)%MAXV; //该顶点进队
                queue[rear]=p->adjvex;



		/*************End6********************/			
				
           	}
           	p=p->nextarc;              		/*找下一个邻接顶点*/
		}
}
	printf("\n");
}
点个赞呗!谢谢您!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小白蔡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值