5-6 列出连通集 (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 }



#include<iostream>


#define MAX_VERTEX_NUM 10
using namespace std;
//数据结构
typedef struct ArcNode{//依附结点
	int adjvex;			//弧所指的顶点的位置
	struct ArcNode* nextatc;//下一条弧的指针

} ArcNode;
typedef struct VNode{//头结点
	int seque;//顶点信息
	ArcNode *firstarc;//指向第一条弧的指针
}VNode, AdjList[MAX_VERTEX_NUM];
//生成指针
ArcNode*newArc(int node)
{
	ArcNode*tmp = new ArcNode;
	tmp->adjvex = node;
	tmp->nextatc = NULL;
	return tmp;
}
//插入结点
void insert(VNode &vnode, int node)
{
	if (!vnode.firstarc)//首次插入
		vnode.firstarc = newArc(node);
	else//按序插入
	{
		//插入在头结点和第一个子节点的情况
		if (node<vnode.firstarc->adjvex)
		{
			ArcNode*tmp = newArc(node);
			tmp->nextatc = vnode.firstarc;
			vnode.firstarc = tmp;
			return;
		}
		ArcNode *adj = vnode.firstarc;//判断大小
		ArcNode*pre = adj;//前一个指针
		while (node > adj->adjvex && adj->nextatc!=NULL)//找到插入位置
		{
			pre = adj;
			adj = adj->nextatc;
		}
		if (adj->adjvex < node)//按从小到大的顺序插入,邻接表
			adj->nextatc = newArc(node);
		else
		{
			pre->nextatc = newArc(node);
			pre->nextatc->nextatc = adj;
			return;
		}
	}
}
void traverse(const AdjList list, int seq, int*flag)
{
	if (!flag[seq])//判断标志位,0则输出
	{
		cout <<" "<<list[seq].seque;//打印头结点
		flag[seq] = 1;
		if (list[seq].firstarc){//判断第一个子结点是否为0
			traverse(list, list[seq].firstarc->adjvex, flag);
			ArcNode*tmp = list[seq].firstarc;
			tmp = tmp->nextatc;
			while (tmp)//子节点的遍历
			{
				traverse(list, tmp->adjvex, flag);
				tmp = tmp->nextatc;

			}
		}
	}


}
void DFS(const AdjList list, int num,int*flag)
{
	//深度遍历求连通集
	for (int i = 0; i < num; i++)
	{
		if (!flag[i])//判断标志位,0则输出
		{
			cout << "{";
			traverse(list, i, flag);
			cout << " }" << endl;
		}
	}
		
}
void traverseBFS(const AdjList list, int seq, int*flag,int *stack,int &left,int&right)
{
	
	if (!flag[seq])//判断标志位,0则输出
	{
		cout << " " << list[seq].seque;//打印头结点
		flag[seq] = 1;
	}
		if (list[seq].firstarc){//判断第一个子结点是否为0
			ArcNode*tmp = list[seq].firstarc;
			while (tmp)//子节点的遍历
			{
				if (!flag[tmp->adjvex])//为打印的子结点入栈
				stack[right++] = tmp->adjvex;
				tmp = tmp->nextatc;
			}
		}//if (list[seq].firstarc)
		while (left != right)//子结点出栈
		{
			traverseBFS(list, stack[left++], flag, stack,left, right);
		}
		

	
}
void BFS(const AdjList list, int num, int*flag)
{
	//广度遍历,求连通集
	int stack[100] = { 0 };
	int left = 0,right = 0;
	for (int i = 0; i < num; i++)
	{
		if (!flag[i])//判断标志位,0则输出
		{
			cout << "{";
			traverseBFS(list, i, flag,stack,left,right);
			cout << " }" << endl;
		}
	}
}

int main()
{
	AdjList list;
	//输入弧
	int N, E;//输入顶点数和边数
	cin >> N >>E;
	//构造表头向量并初始化指针
	for (int i = 0; i < N; i++)
	{
		list[i].seque = i;
		list[i].firstarc = NULL;
	}
	//输入各弧 构造无向图
	int fir, sec;
	for (int i = 0; i < E; i++)
	{
		cin >> fir >> sec;
		insert(list[fir], sec);
		insert(list[sec], fir);
	}
	//深度遍历
	int flag[MAX_VERTEX_NUM] = { 0 };//访问标志数组
	int flag1[MAX_VERTEX_NUM] = { 0 };//访问标志数组
	DFS(list,N, flag);
	BFS(list, N, flag1);

	//释放内存

	system("pause");
	return 0;
}


//使用邻接矩阵 更快速,注意不要使用头结点


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值