zoukankan      html  css  js  c++  java
  • 列出图的连通集

    • 题目来源:

    浙江大学在慕课网上开设的《数据结构》课,陈越老师、何钦铭老师主讲,课后作业的一道题。

    • 题目描述:

    • 思路:

    非常基础的一道题,主要考察图的DFS遍历和BFS遍历,最后注意输出的格式就可以了。

    • C语言实现:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define MaxVerterNum 100  //最大定点数设为100
    #define INFINITY 65535  //无穷设为双字节无符号整数的最大值65535
    
    typedef int WeightType;  //边的权值设为int类型
    typedef char DataType;  //顶点存储的数据类型设置为字符类型
    typedef int Vertex;  //用顶点下标表示顶点,为整型
    
    bool Visited[MaxVerterNum];
    
    struct QNode
    {
    	int* Data;  //存储元素的数组
    	int Front;  //队列的头指针
    	int Rear;  //队列的尾指针
    	int MaxSize;  //队列的最大容量
    };
    
    //创建一个队列
    struct QNode* CreateQueue(int MaxSize)
    {
    	struct QNode* Q = (struct QNode*)malloc(sizeof(struct QNode));
    	Q->Data = (int *)malloc(MaxSize * sizeof(int));
    	Q->Front = Q->Rear = 0;
    	Q->MaxSize = MaxSize;
    	return Q;
    }
    
    bool IsFull(struct QNode* Q)
    {
    	return ((Q->Rear + 1) % Q->MaxSize) == Q->Front;
    }
    
    //在队列尾插入一个元素
    //参数 struct QNode* Q 要操作的队列
    //     int x  待插入的元素
    bool AddQ(struct QNode* Q, int x)
    {
    	if (IsFull(Q))  //判断队列是否为空
    	{
    		printf("队列满,不能再插入元素
    ");
    		return false;
    	}
    	else
    	{
    		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
    		Q->Data[Q->Rear] = x;
    		return true;
    	}
    }
    
    //判断队列是否为空
    bool IsEmpty(struct QNode* Q)
    {
    	return (Q->Front == Q->Rear);
    }
    //在队列头部删除一个元素
    int DeleteQ(struct QNode* Q)
    {
    	if (IsEmpty(Q))
    	{
    		printf("队列为空
    ");
    		return false;
    	}
    	else
    	{
    		Q->Front = (Q->Front + 1) % Q->MaxSize;
    		return Q->Data[Q->Front];
    	}
    
    }
    
    struct GNode 
    {
    	int Nv;  //顶点数
    	int Ne;  //边数
    	WeightType G[MaxVerterNum][MaxVerterNum];  //邻接矩阵
    	DataType Data[MaxVerterNum][MaxVerterNum];  //存顶点的数据
    	/*如果顶点无数据,此时Data[]可以不出现*/
    };
    //描述边的类型
    struct ENode
    {
    	Vertex V1, V2;  //有向边<V1,V2>
    	WeightType Weight;  //权重
    };
    //作用:初始化一个有VertexNum个顶点但没有边的图
    struct GNode* CreateGraph(int VertexNum)
    {
    	Vertex V, W;
    	struct GNode* Graph;
    	Graph = (struct GNode*)malloc(sizeof(struct GNode));  //建立图
    	Graph->Nv = VertexNum;
    	Graph->Ne = 0;
    
    	//初始化邻接矩阵
    	for (V = 0;V < Graph->Nv;V++)
    	{
    		for (W = 0;W < Graph->Nv;W++)
    		{
    			Graph->G[V][W] = INFINITY;
    		}
    	}
    	return Graph;
    }
    
    //作用:在图中插入边
    void InsertEdge(struct GNode* Graph,struct ENode* E)
    {
    	////插入边<V1,V2>
    	//Graph->G[E->V1][E->V2] = E->Weight;
    	////若是无向图,还需要插入<V2,V1>
    	//Graph->G[E->V2][E->V1] = E->Weight;
    
    	//插入边<V1,V2>
    	Graph->G[E->V1][E->V2] = 1;
    	//若是无向图,还需要插入<V2,V1>
    	Graph->G[E->V2][E->V1] = 1;
    }
    //作用:构建一个图,供主函数调用
    struct GNode* BulidGraph()
    {
    	Vertex V;
    	int NV;
    	struct ENode* E;
    	struct GNode* Graph;
    	scanf("%d",&NV);  //读入顶点个数
    	Graph = CreateGraph(NV);
    	scanf("%d",&(Graph->Ne));  //读入边数
    
    	if (Graph->Ne != 0)
    	{
    		E = (struct ENode*)malloc(sizeof(struct ENode));
    		for (int i = 0;i < Graph->Ne;i++)
    		{
    			////如果权重不是整型,Weight的读入格式要改
    			//scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
    			scanf("%d %d", &E->V1, &E->V2);
    			InsertEdge(Graph,E);
    		}
    	}
    
    	////如果顶点有数据的话,读入数据
    	//for (V = 0;V < Graph->Nv;V++)
    	//{
    	//	scanf("%c",&(Graph->Data[V]));
    	//}
    
    	return Graph;
    }
    
    void Visit(Vertex V)
    {
    	printf(" %d",V);
    }
    //这个DFS是我自己写的
    //void DFS(struct GNode* Graph,Vertex V,void(* Visit)(Vertex))
    //{
    //	Vertex W;
    //	Visit(V);
    //	Visited[V] = true;
    //
    //	for (W = V + 1; W < Graph->Nv; W++)
    //	{
    //		if (Graph->G[V][W] == 1)
    //		{
    //			if (!Visited[W])
    //			{
    //				DFS(Graph, W, Visit);
    //			}
    //		}
    //	}
    //}
    
    void DFS(struct GNode* Graph, Vertex V, void(*Visit)(Vertex))
    {
    	Vertex j;
    	Visited[V] = true;
    	Visit(V);
    
    	for (j = 0;j < Graph->Nv;j++)
    	{
    		if (Graph->G[V][j] == 1 && !Visited[j])
    		{
    			DFS(Graph,j,Visit);
    		}
    	}
    }
    
    void DFSTraverser(struct GNode* Graph)
    {
    	int i = 0;
    	//初始化所有顶点都是未访问的状态
    	for (i = 0;i < Graph->Nv;i++)
    	{
    		Visited[i] = false;
    	}
    
    	for (i=0;i < Graph->Nv;i++)
    	{
    		if (!Visited[i])
    		{
    			printf("{");
    			DFS(Graph,i,Visit);    
    			printf(" }
    ");
    		}
    	}
    }
    
    bool IsEdge(struct GNode* Graph,Vertex V,Vertex W)
    {
    	return Graph->G[V][W] < INFINITY ? true : false;
    }
    
    void BFS(struct GNode* Graph, Vertex S, void(*Visit)(Vertex))
    {
    	struct QNode* Q;
    	Vertex V, W;
    	Q = CreateQueue(20);
    
    	Visited[S] = true;
    	Visit(S);
    	AddQ(Q,S);
    
    	while (!IsEmpty(Q))
    	{
    		V = DeleteQ(Q);
    		for (W = 0;W < Graph->Nv;W++)
    		{
    			//若W是V的邻接点 并且 没有访问过
    			if (!Visited[W] && IsEdge(Graph,V,W))
    			{
    				Visit(W);  //访问节点
    				Visited[W] = true;
    				AddQ(Q,W);
    			}
    		}
    	}
    }
    void BFSTraverser(struct GNode* Graph)
    {
    	int i = 0;
    	//初始化所有顶点都是未访问的状态
    	for (i = 0; i < Graph->Nv; i++)
    	{
    		Visited[i] = false;
    	}
    
    	for (i = 0; i < Graph->Nv; i++)
    	{
    		if (!Visited[i])
    		{
    			printf("{");
    			BFS(Graph, i, Visit);
    			printf(" }
    ");
    		}
    	}
    }
    
    int main()
    {
    	struct GNode* Graph = BulidGraph();
    	// printf("图建立完毕.
    ");
    	DFSTraverser(Graph);
    	BFSTraverser(Graph);
    	// system("pause");
    	return 0;
    }
    
  • 相关阅读:
    女程序员这么少是因为怕秃头?如果你这样想,那就错了...
    使用简单的c#示例的坚实的架构原则
    第1部分设计模式FAQ(培训)
    为什么微软部分类和Java不?
    现实世界四部分类和部分方法的使用
    回到基础:n层ASP的异常管理设计指南。网络应用
    学习c#(第9天):理解c#中的事件(一种见解)
    EventBroker:同步和异步通知组件,松散耦合的事件处理
    潜水在OOP(第一天):多态和继承(早期绑定/编译时多态)
    学习c#(第8天):c#中的索引器(一种实用方法)
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11367543.html
Copyright © 2011-2022 走看看