数据结构实验7---- 图的两种遍历方法及对应的生成树

实验题目

实验题目: 图的两种遍历方法及对应的生成树自己编写源程序,把图的深度优先遍历、广度优先遍历改为输出深度优先生成树、广度优先生成树。 

实验说明:

        (1)输入图;

        (2)求从顶点3出发遍历序列改为显示深度优先生成树和广度优先生成树。

实验内容

1.问题设计分析

        图的深度优先遍历和广度优先遍历是常用的图遍历算法。其中,深度优先遍历通过递归或栈实现,它会遍历图中所有的节点,并将它们标记为已经访问过,但并没有记录节点间的关系;广度优先遍历则通过队列实现,它同样会遍历图中所有的节点,但会先访问距离起始节点近的节点,并记录节点间的关系。

        而深度优先生成树和广度优先生成树则是在遍历过程中,以图中节点的连接关系为基础建立起一棵基于图的树。

        深度优先生成树的实现方法如下:

                (1) 从起始节点开始访问

                (2)访问当前节点并将其标记为已经访问过

                (3) 遍历与该节点直接相连的且未被访问过的节点,对每个节点递归进行上述步骤,并将其与当前节点建立连接关系。该方法和深度优先遍历的实现类似,唯一的区别在于需要记录和建立节点之间的连接关系。通过这种方式遍历整个图,形成的树即为深度优先生成树。

        广度优先生成树的实现方法如下:

                (1)从起始节点开始访问,并将其加入队列中

                (2)将队列头节点出队,并访问该节点并将其标记为已经访问过

                (3)遍历与该节点直接相连的且未被访问过的节点,并将其加入队列中,并记录节点之间的连接关系

                (4)重复执行第2、3步,直到队列为空。通过这种方式遍历整个图,形成的树即为广度优先生成树。

2.程序编码

        代码如下:

#include<stdio.h>
#include<malloc.h>
#define INF 32767
#define MAXV 100
#define MaxSize 100
int visited[MAXV]={0};
typedef char InfoType;
typedef struct ANode
{
	int adjvex;
	struct ANode *nextarc;
	int weight;	
}ArcNode;
typedef struct Vnode
{
	InfoType info;
	int count;
	ArcNode *firstarc;
}VNode;
typedef struct
{
	VNode adjlist[MAXV];
	int n,e;
}AdjGraph;
void CreatAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)
{
	int i,j;
	ArcNode *p;
	G=(AdjGraph *)malloc(sizeof(AdjGraph));
	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(A[i][j]!=0&&A[i][j]!=INF)
			{
				p=(ArcNode *)malloc(sizeof(ArcNode));
				p->adjvex=j;
				p->weight=A[i][j];
				p->nextarc=G->adjlist[i].firstarc;
				G->adjlist[i].firstarc=p;
			}
	G->n=n;G->e=n;
}
void DispAdj(AdjGraph *G)
{
	ArcNode *p;
	for(int i=0;i<G->n;i++)
	{
		p=G->adjlist[i].firstarc;
		printf("%3d:",i);
		while(p!=NULL)
		{
			printf("%3d[%d]→",p->adjvex,p->weight);
			p=p->nextarc;
		}
		printf("^\n");
	}
}
void DestroyAdj(AdjGraph *&G)
{
	ArcNode *pre,*p;
	for(int i=0;i<G->n;i++)
	{
		pre=G->adjlist[i].firstarc;
		if(pre!=NULL)
		{
			p=pre->nextarc;
			while(p!=NULL)
			{
				free(pre);
				pre=p;p=p->nextarc;
			}
			free(pre);
		}
	}
	free(G);
}
void DFSTree(AdjGraph *G,int v)
{
	ArcNode *p;
	visited[v]=1;
	p=G->adjlist[v].firstarc;
	while(p!=NULL)
	{
		if(visited[p->adjvex]==0)
		{
			printf("(%d,%d)",v,p->adjvex);
			DFSTree(G,p->adjvex);
		}
		p=p->nextarc;
	}	
}
void BFSTree(AdjGraph *G,int v)
{
	int w,i;
	int qu[MAXV];
	int front=0,rear=0;
	ArcNode *p;
	int visited[MAXV];
	for(i=0;i<G->n;i++)
	visited[i]=0;
	visited[v]=1;
	rear++;
	qu[rear]=v;
	while(front!=rear)
	{
		front=(front+1)%MAXV;
		w=qu[front];
		p=G->adjlist[w].firstarc;
		while(p!=NULL)
		{
			if(visited[p->adjvex]==0)
			{
				printf("(%d,%d)",w,p->adjvex);
				visited[p->adjvex]=1;
				rear=(rear+1)%MAXV;
				qu[rear]=p->adjvex;
			}
			p=p->nextarc;
		}
	}
	printf("\n");
}
int main()
{
	AdjGraph *G;
	int A[MAXV][MAXV];
	int n=11,e=13;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			A[i][j]=0;
	A[0][1]=1;A[0][2]=1;A[0][3]=1;
	A[1][0]=1;A[1][4]=1;A[1][5]=1;
	A[2][0]=1;A[2][3]=1;A[2][5]=1;A[2][6]=1;
	A[3][0]=1;A[3][2]=1;A[3][7]=1;
	A[4][1]=1;A[5][1]=1;A[5][2]=1;
	A[6][2]=1;A[6][7]=1;A[6][8]=1;A[6][9]=1;
	A[7][3]=1;A[7][6]=1;A[7][10]=1;
	A[8][6]=1;A[9][6]=1;A[10][7]=1;	
	CreatAdj(G,A,n,e);
	printf("图G的邻接表:\n");
	DispAdj(G);
	int v=3;
	printf("深度优先生成树:\n");DFSTree(G,v);printf("\n");
	printf("广度优先生成树:\n");BFSTree(G,v);
	DestroyAdj(G);
	return 1;
}

 3.运行结果和分析

        在实现本算法之前,我们需要图的基本运算算法和图的存储算法:本次用到的是邻接表类型存储的图并且添加了创建图的邻接表、输出图的邻接表、销毁图的邻接表等算法。DFSTree为深度优先生成树算法、BFSTree广度优先生成树算法。

4.实验小结

本次实验通过深度优先生成树和广度优先生成树的实现,可以建立起基于图的树结构,便于对图的结构进行理解和处理。同时也可以让我们更好地理解深度优先遍历和广度优先遍历算法的实现过程和原理。在编写代码的过程中,需要注意记录节点间的连接关系,并根据具体情况选择合适的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值