六度空间

  • 题目来源;

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

  • 题目描述:

  • 题目思路:

使用BFS即可。

  • C语言实现
#define _CRT_SECURE_NO_WARNINGS
//使用邻接表来存储图
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// #include "queue.h"

/************************/
// #include "queue.h"
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("队列满,不能再插入元素\n");
		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("队列为空\n");
		return false;
	}
	else
	{
		Q->Front = (Q->Front + 1) % Q->MaxSize;
		return Q->Data[Q->Front];
	}

}
/****************************/
#define MaxVerterNum 1000

bool Visited[MaxVerterNum];
//边的定义
struct ENode
{
	int V1;
	int V2;  //有向边<V1,V2>
	int Weight;  //权重
};

//邻接点的定义
struct AdjNode
{
	int AdjV;  //邻接点的下标
	int Weight;  //边的权值
	struct AdjNode* Next;  //指向下一个邻接点的指针
};

//顶点表头结点的定义
typedef struct Vnode
{
	struct AdjNode* FirstEdge;  //边表头指针
	char Data;  //存储顶点的数据  //这里设为字符型
}AdjList[MaxVerterNum];

//图节点的定义
struct GNode
{
	int Nv;  //顶点数
	int Ne;  //边数
	AdjList G;  //邻接表
};

struct GNode* CreateGraph(int VertexNum)
{
	//初始化一个有VertexNum个顶点但没有边的图
	int V;
	struct GNode* Graph;
	
	//建立图
	Graph = (struct GNode*)malloc(sizeof(struct GNode));
	Graph->Ne = 0;
	Graph->Nv = VertexNum;

	//初始化邻接表头指针
	//这里默认顶点编号从0开始,到(Graph->Nv - 1)
	for (V = 0; V < Graph->Nv;V++)
	{
		Graph->G[V].FirstEdge = NULL;
	}

	return Graph;
}

void InsertEdge(struct GNode* Graph,struct ENode* E)
{
	struct AdjNode* NewNode;
	NewNode = (struct AdjNode*)malloc(sizeof(struct AdjNode));
	NewNode->AdjV = E->V2;
	//NewNode->Weight = E->Weight;
	NewNode->Weight = 1;

	//将V2插入V1的表头
	NewNode->Next = Graph->G[E->V1].FirstEdge;
	Graph->G[E->V1].FirstEdge = NewNode;

	//若是无向图,还要插入边<V2,V1>
	NewNode = (struct AdjNode*)malloc(sizeof(struct AdjNode));
	NewNode->AdjV = E->V1;
	//NewNode->Weight = E->Weight;
	NewNode->Weight = 1;

	//将V1插入V2的表头
	NewNode->Next = Graph->G[E->V2].FirstEdge;
	Graph->G[E->V2].FirstEdge = NewNode;
}

struct GNode* BuildGraph()
{
	struct GNode* Graph;
	struct ENode* E;
	int V;
	int Nv, i;

	scanf("%d",&Nv);  //读入顶点的个数
	Graph = CreateGraph(Nv);  //初始化有Nv个顶点,但没有边的图
	scanf("%d",&(Graph->Ne));  //读入边数

	if (Graph->Ne != 0)  //如果有边
	{
		//建立边节点
		E = (struct ENode*)malloc(sizeof(struct ENode));
		
		for (int i = 0;i < Graph->Ne;i++)
		{
			//读入格式为 起点 终点 权重
			//scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
			scanf("%d %d", &E->V1, &E->V2);
			E->V1--;
			E->V2--;
			InsertEdge(Graph,E);
		}
	}

	//如果顶点有数据的话,读入数据
	//for (int i = 0; i < Graph->Nv;i++)
	//{
	//	scanf("%c",&(Graph->G[i].Data));
	//}

	return Graph;
}

void InitializeVisited(int Nv)
{
	int i = 0;
	for (;i < Nv;i++)
	{
		Visited[i] = false;
	}
}

int SDS_BFS(struct GNode* Graph,int S)
{
	int V = 0;
	int Tail = 0;
	int Last = S;
	int Level = 0;
	int Count = 1;
	struct AdjNode* W = NULL;
	struct QNode* Q = CreateQueue(MaxVerterNum);
	Visited[S] = true; //标记S已经被访问
	AddQ(Q, S);

	while (!IsEmpty(Q))
	{
		V = DeleteQ(Q);
		for (W = Graph->G[V].FirstEdge; W ; W = W->Next)
		{
			if (!Visited[W->AdjV])  
			{
				Visited[W->AdjV] = true;  //标记W->AdjV已经被访问
				//printf("%d.\n",W->AdjV);
				Count++;
				Tail = W->AdjV;  //当前的层尾
				AddQ(Q, W->AdjV);
			}
		}
		if (V == Last)  //如果上一层的最后一个顶点弹出了
		{
			Level++;
			Last = Tail;
		}
		if (Level == 6)
		{
			break;
		}
	}
	return Count;
}

int main()
{
	int count = 0;
	struct GNode* Graph = BuildGraph();
	for (int i = 0;i < Graph->Nv;i++)
	{
		InitializeVisited(Graph->Nv);
		count = SDS_BFS(Graph,i);
		printf("%d: %.2f%%\n",i+1,100.0 * (double)count/(double)Graph->Nv);
	}
	// system("pause");
	return 0;
}
posted @ 2019-08-20 11:03  尚修能的技术博客  阅读(643)  评论(0编辑  收藏  举报