PTA_15_06_图1 _列出连通集

PTA15_06_图1 _列出连通集

题目描述:

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

输入格式

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

8 6//N E
0 7
0 1
2 0
4 1
2 4
3 5

输出格式

按照"{ v1 v2 … v**k }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

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

分析

DFS:深度优先遍历,相当于树的前序遍历

BFS:广度优先遍历,相当于树的层序遍历

连通集:两顶点之间存在路径相互连通

  • 本题适合用邻接矩阵进行实现
  • 深度优先遍历,采用递归的方式进行实现
  • 广度优先遍历,结合队列来实现

队列(数组)实现

#pragma once
#include<stdio.h>
#include<iostream>

#define MAXSIZE 100
struct QNode
{
	int data[MAXSIZE];
	int front;//头
	int rear;//尾
};
typedef QNode* Queue;

int InitQueue(Queue q)
{
	q->front = 0;
	q->rear = 0;
	return 0;
}

int IsQueueEmpty(Queue q)
{
	if (q->front == q->rear)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int EnQueue(Queue q,int i)
{
	//首先判断队列是否满
	if ((q->rear + 1) % MAXSIZE == q->front)//队列满了
	{
		return 0;
	}
	q->data[q->rear] = i;//把该值赋给队尾
	q->rear = (q->rear) + 1;//队尾向后移动一位
}

int DeQueue(Queue q, int* e)//e用来保存要删除的队头元素
{
	if (q->front == q->rear)//首先先判断队列是不是空的
		return 0;
	*e = q->data[q->front];//将队头元素赋给e
	q->front = (q->front + 1) % MAXSIZE;//front向后移动,若移动的值是最后,则回到队头
	return 1;
}

深度优先遍历和广度优先遍历算法实现

#include<stdio.h>
#include<iostream>
#include"queue.h"

using namespace std;

#define MAXVEX 9
#define MAXEDGE 9

struct GNode
{
	int vex[MAXVEX];//顶点集
	int arc[MAXVEX][MAXVEX];//邻接矩阵
	int numvex;
	int numedge;
};

typedef struct GNode* Mgraph;
bool visited[MAXVEX];//作为顶点访问的标识符


void CreateGraph(Mgraph graph)
{
	int i, j, k;
	cin >> graph->numvex >> graph->numedge;

	for (i = 0; i < graph->numvex; i++)
	{
		graph->vex[i] = i;//定义顶点的值
	}

	for (i = 0; i < graph->numvex; i++)
	{
		for (j = 0; j < graph->numvex; j++)
		{
			graph->arc[i][j] = 0;//邻接矩阵初始化
		}
	}

	for (i = 0; i < graph->numedge; i++)
	{
		cin >> j >> k;
		graph->arc[j][k] = 1;//往邻接矩阵中填入权重,无权的化,设置为1
	}

	for (i = 0; i < graph->numedge; i++)
	{
		for (j = 0; j < graph->numedge; j++)
		{
			if (graph->arc[i][j])
			{
				graph->arc[j][i] = graph->arc[i][j];
			}
			if (graph->arc[j][i])
			{
				graph->arc[i][j] = graph->arc[j][i];
			}
		}
	}
}


void DFS(Mgraph graph, int i)
{
	int j;
	visited[i] = true;//表明已经检查过i了
	cout << graph->vex[i] << " ";//将检查的点输出
	for (j = 0; j < graph->numvex; j++)
	{
		if (graph->arc[i][j] == 1 && !visited[j])//找与i有边的j,且j未被标记过
		{
			//递归进行查找
			DFS(graph, j);
		}
	}
}



//DFS 深度优先遍历

void DFSTraver(Mgraph graph)
{
	int i;
	for (i = 0; i < graph->numvex; i++)
	{
		visited[i] = false;//初始化,所有顶点都是未访问状态
	}
	for (i = 0; i < graph->numvex; i++)
	{
		if (!visited[i])
		{
			cout << "{" << " ";
			DFS(graph, i);//去找去判断是否有下一个顶点
			cout << "}" << endl;
		}
	}

}

//建立层序遍历,广度遍历
void BFS(Mgraph graph)
{
	int i, j, k;
	Queue q;
	q = (Queue)malloc(sizeof(struct QNode));
	for (i = 0; i < graph->numvex; i++)
	{
		visited[i] = false;
	}
	InitQueue(q);

	for (i = 0; i < graph->numvex; i++)
	{
		if (!visited[i])
		{
			visited[i] = true;//找到了这个值然后标记
			cout << "{" << " " << graph->vex[i]<<" ";
			EnQueue(q, i);//将这个顶点入队

			while (!IsQueueEmpty(q))//若当前队列不为空
			{
				DeQueue(q, &k);//将出队元素的坐标赋给k;
				for (j = 0; j < graph->numvex; j++)
				{
					if (graph->arc[k][j] == 1 && !visited[j])
					{
						visited[j] = true;
						cout << graph->vex[j] << " ";
						EnQueue(q, j);
					}
				}
			}

			cout << "}" << endl;
		}
	}
}


int main()
{
	Mgraph graph;
	graph = (Mgraph)malloc(sizeof(struct GNode));
	CreateGraph(graph);
	DFSTraver(graph);
	BFS(graph);
}

之前断更了一段时间,准备期末考试,准备了一两个多星期,成绩还是不理想,现在想透了,科研与我不太适合,还不如早点为未来做打算。本次实验主要参考的大话数据结构的邻接矩阵的BFS和DFS,在这代码的基础上自己重新修改,并手敲了一遍。好记性不如烂笔头。最后的结构,还是有一个小错误,但总体功能实现了,总感觉PTA的那个得分设置有点难受,功能能实现,我就觉得差不多了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值