06-图1 列出连通集 (25分)

给定一个有NN个顶点和EE条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N-1N1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:

输入第1行给出2个整数NN(0<N\le 100<N10)和EE,分别是图的顶点数和边数。随后EE行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

输出格式:

按照"{ v_1v1 v_2v2 ... v_kvk }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

输入样例:

8 6
0 7
0 1
2 0
4 1
2 4
3 5

输出样例:

{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

思路:

开始的时候我认为邻接表和邻接矩阵都是ok的,于是就先码了邻接表的代码,如下:

/* 邻接表 */
#include <queue> 
#include <stdlib.h> 
#include <stdio.h> 
#define MaxVertexNum 100    /* 最大顶点数设为100 */
typedef int Vertex;         /* 用顶点下标表示顶点,为整型 */
typedef int WeightType;        /* 边的权值设为整型 */
typedef char DataType;        /* 顶点存储的数据类型设为字符型 */


using namespace std;
/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;      /* 有向边<V1, V2> */
    WeightType Weight;  /* 权重 */
};
typedef PtrToENode Edge;
 
/* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;        /* 邻接点下标 */
    WeightType Weight;  /* 边权重 */
    PtrToAdjVNode Next;    /* 指向下一个邻接点的指针 */
};

/* 顶点表头结点的定义 */
typedef struct Vnode{
    PtrToAdjVNode FirstEdge;/* 边表头指针 */
    DataType Data;            /* 存顶点的数据 */
    /* 注意:很多情况下,顶点无数据,此时Data可以不用出现 */
} AdjList[MaxVertexNum];    /* AdjList是邻接表类型 */
 
/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;     /* 顶点数 */
    int Ne;     /* 边数   */
    AdjList G;  /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */

void CreatEdge(LGraph Graph,int V,int W)
{
	//令下标为V的头节点的指针域指向W 
	PtrToAdjVNode p=(PtrToAdjVNode)malloc(sizeof(AdjVNode));
	p->AdjV=W;
	p->Next=Graph->G[V].FirstEdge;
	Graph->G[V].FirstEdge=p;
	
	//令下标为W的头节点的指针域指向V 
	PtrToAdjVNode q=(PtrToAdjVNode)malloc(sizeof(AdjVNode));
	q->AdjV=V;
	q->Next=Graph->G[W].FirstEdge;
	Graph->G[W].FirstEdge=q;	
}

void DFS(LGraph Graph,int V,bool Visited[])
{
	PtrToAdjVNode W;
	
	printf("%d ",V);
	Visited[V]=true;
	
	for(W=Graph->G[V].FirstEdge;W!=NULL;W=W->Next)
	{
		if(!Visited[W->AdjV])
		{
			DFS(Graph,W->AdjV,Visited);
		}
	}
}

void BFS(LGraph Graph,int S,bool Visited[])
{ /* 以S为出发点对邻接矩阵存储的图Graph进行BFS搜索 */
	queue<int> q;
	q.push(S);/* S入队列 */
	printf("%d ",S);
	Visited[S]=true;/* 标记S已访问 */
	
	int V;
	while(!q.empty())
	{
		V=q.front();
		q.pop();/* 弹出V */
		PtrToAdjVNode p=Graph->G[V].FirstEdge;
		for(;p!=NULL;p=p->Next)		//对于所有与点V相连接的点 
		{
			if(!Visited[p->AdjV])
			{
				q.push(p->AdjV);
				printf("%d ",p->AdjV);
				Visited[p->AdjV]=true;
			}
		}		
	}
}

int main()
{	
	LGraph Graph=(LGraph)malloc(sizeof(GNode));
	scanf("%d",&Graph->Nv); 
	scanf("%d",&Graph->Ne);
	for(int i=0;i<Graph->Nv;i++)
	{
		Graph->G[i].FirstEdge=NULL;	//邻接表头指针初始化为NULL 
	}
	
	int V=0,W=0;
	for(int i=0;i<Graph->Ne;i++)//输入边的端点信息 
	{
		scanf("%d",&V); 
		scanf("%d",&W);
		CreatEdge(Graph,V,W);
	}
	
	bool Visited[Graph->Nv];
	for(int i=0;i<Graph->Nv;i++)//建一个bool类型数组,记录对应下标的端点是否访问过 
	{
		Visited[i]=false;//初始化 
	}
	
	for(int i=0;i<Graph->Nv;i++)
	{
		if(!Visited[i])
		{
			printf("{ ");
			DFS(Graph,i,Visited);
			printf("}\n");
		}
	}
	
	

	for(int i=0;i<Graph->Nv;i++)//重置Visited数组 
	{
		Visited[i]=false;
	}
	
	for(int i=0;i<Graph->Nv;i++)
	{
		if(!Visited[i])
		{
			printf("{ ");
			BFS(Graph,i,Visited);
			printf("}\n");
		}
	}	
	return 0;
} 

但是经过运行,发现尽管输出的数值顺序不合要求。经过观察,发现BFS的输出是有顺序的,按照从小到大的顺序排序。因此更改了部分代码,改为用邻接矩阵的方式来实现。

/* 图的邻接矩阵表示法 */
#include <queue> 
#include <stdlib.h> 
#include <stdio.h> 
#define MaxVertexNum 100    /* 最大顶点数设为100 */
#define INFINITY 65535        /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex;         /* 用顶点下标表示顶点,为整型 */
typedef int WeightType;        /* 边的权值设为整型 */
typedef char DataType;        /* 顶点存储的数据类型设为字符型 */

using namespace std;
/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode{
	Vertex V1,V2;		/* 有向边<V1, V2> */
	WeightType Weight;	/* 权重 */
};
typedef PtrToENode Edge;

/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{
	int Nv;				/* 顶点数 */
	int Ne;				/* 边数   */
	WeightType G[MaxVertexNum][MaxVertexNum];	/* 邻接矩阵 */
	DataType Data[MaxVertexNum];		/* 存顶点的数据 */
    /* 注意:很多情况下,顶点无数据,此时Data[]可以不用出现*/
};
typedef PtrToGNode MGraph;
 

void CreatEdge(MGraph Graph,int V,int W)
{
	Graph->G[V][W]=1;
	Graph->G[W][V]=1;	
}

void DFS(MGraph Graph,int V,bool Visited[])
{
	int W;
	
	printf("%d ",V);
	Visited[V]=true;
	
	for(W=0;W<Graph->Nv;W++)
	{
		if(!Visited[W]&&Graph->G[V][W]==1)
		{
			DFS(Graph,W,Visited);
		}
	}
}

void BFS(MGraph Graph,int S,bool Visited[])
{
	queue<int> q;
	int V;
	q.push(S);
	printf("%d ",S);
	Visited[S]=true;
	
	while(!q.empty())
	{
		V=q.front();
		q.pop();
		for(int W=0;W<Graph->Nv;W++)
		{
			if(!Visited[W]&Graph->G[V][W]==1)
			{
				q.push(W);
				printf("%d ",W);
				Visited[W]=true;
			}
		}		
	}
}

int main()
{	
	MGraph Graph=(MGraph)malloc(sizeof(GNode));
	scanf("%d",&Graph->Nv); 
	scanf("%d",&Graph->Ne);
	for(int i=0;i<Graph->Nv;i++)
	{
		for(int j=0;j<Graph->Nv;j++)
		{
			Graph->G[i][j]=INFINITY;		
		}		
	}
	
	int V=0,W=0;
	for(int i=0;i<Graph->Ne;i++)
	{
		scanf("%d",&V); 
		scanf("%d",&W);
		CreatEdge(Graph,V,W);
	}	
	
	bool Visited[Graph->Nv];
	for(int i=0;i<Graph->Nv;i++)
	{
		Visited[i]=false;
	}	
	for(int i=0;i<Graph->Nv;i++)
	{
		if(!Visited[i])
		{
			printf("{ ");
			DFS(Graph,i,Visited);
			printf("}\n");
		}
	}	

	for(int i=0;i<Graph->Nv;i++)
	{
		Visited[i]=false;
	}
	
	for(int i=0;i<Graph->Nv;i++)
	{
		if(!Visited[i])
		{
			printf("{ ");
			BFS(Graph,i,Visited);
			printf("}\n");
		}
	}	
	return 0;
} 







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值