重庆邮电大学数据结构实验七

实验七 基于广度优先搜索的六度空间
理论验证
一、实验目的
1. 掌握图的邻接矩阵和邻接表表示法,掌握采用邻接矩阵和邻接表表示法创
建图的算法。
2. 掌握图的广度优先搜索算法。
3. 掌握基于图的广度优先搜索的六度空间理论验证的算法。
二、实验内容
问题描述
六度空间 理论又称作 六度分隔 (Six Degrees of Separation)” 理论。这个理论
可以通俗地阐述为 :“ 你和任何一个陌生人之间所间隔的人不会超过六个,也就是
说,最多通过五个人你就能够认识任何一个陌生人。 假如给你一个社交网络图,
请你对每个节点计算符合 六度空间 理论的结点占结点总数的百分比。
输入要求
多组数据,每组数据 m+1 行。第一行有两个数字 n m ,代表有 n 个人和
m 组朋友关系。 n 个人的编号为 1 n 。第二行到第 m+1 行每行包括两个数字 a
b ,代表这两个人互相认识。当 n m 都等于 0 时,输入结束。
输出要求
每组数据输出 n 行,对每个结点输出与该结点距离不超过 6 的结点数占结点
总数的百分比,精确到小数点后 2 位。每个结节点输出一行,格式为 结点编号 :(
) 百分比 %”
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MaxS 20
#define MaxE 5
//结构体部分
typedef struct {						//图结构体定义 
	char vex[MaxS];					//顶点数组 
	int vexnum;						//顶点个数 
	int mat[MaxS][MaxS];			//邻接矩阵 
	int arcnum;						//边数 
}Graph;
typedef struct {
	int head, tail;
	int mat[20];						//队列数组 
}Queue;
//全局变量部分
float result[MaxE][MaxS];					//结果存储函数
int cunt;							//用于全局变量遍历 
int state[MaxS];
//函数声明部分
void Init(Graph* a);
int Read(Graph* a);
void Cal(Graph* a);
void show();
float BFS(Graph* a, int s);
void InitQ(Queue* q);				//初始化队列 
void push(Queue* q, int n);			//入队 
int pop(Queue* q);					//出队 
//函数定义部分
void InitQ(Queue* q) {
	q->head = 0;
	q->tail = 0;
}
void push(Queue* q, int n) {
	q->mat[q->tail] = n;
	q->tail++;
}
int pop(Queue* q) {
	q->head++;
	if (q->head > q->tail)return -1;
	return q->mat[q->head - 1];
}
float BFS(Graph* a, int s) {
	int tmp, rs = 0;
	int* len = (int*)malloc(sizeof(int) * (a->vexnum + 1));			//记录到s的距离 
	for (int i = 0; i <= a->vexnum; i++) {
		state[i] = 0;
		len[i] = 0;
	}
	Queue* q = (Queue*)malloc(sizeof(Queue));
	InitQ(q);
	push(q, s);
	state[s] = 1;
	for (int i = 0; i < a->vexnum; i++) {						//总共遍历a->vexnum次
		tmp = pop(q);
		if (tmp == -1)continue;
		for (int j = 1; j <= a->vexnum; j++) {					//每次扫描vexnum个数  
			if (a->mat[tmp][j] == 1 && state[j] == 0) {
				len[j] = len[tmp] + 1;
				state[j] = 1;							//状态变成已访问
				push(q, j);
				continue;
			}
		}
	}
	for (int i = 1; i <= a->vexnum; i++) {
		if (len[i] <= 6 && len[i] != 0)rs += 1;
	}
	for (int i = 1; i <= a->vexnum; i++) {
	}
	free(len);
	free(q);
	return (float)(rs + 1) / a->vexnum * 100;
}
void show() {
	printf("\n                  =================|    -FZC-    |===============                 \n\n");
	printf("FOLLOWING OUTPUT:\n");
	for (int i = 0; i < cunt; i++) {
		printf("[ %d ]\n", i + 1);
		for (int j = 1; j < MaxS; j++) {
			if (result[i][j] == -1)break;
			printf("%d: %.2f%%\n", j, result[i][j]);
		}
	}
}
void Init(Graph* a) {
	a->arcnum = 0;
	a->vexnum = 0;
	for (int i = 0; i < MaxS; i++) {
		a->vex[i] = 0;
		state[i] = 0;
		result[cunt][i] = -1;
		for (int j = 0; j < MaxS; j++) {
			a->mat[i][j] = 0;
		}
	}

}

int Read(Graph* a) {
	int n, m, s, e;
	/*printf("input n,m:");*/
	scanf("%d %d", &n, &m);
	if (n == 0 && m == 0)return 1;			//若均为0则返回1 
	a->vexnum = n;
	a->arcnum = m;
/*	printf("input relationship:\n");*/
	for (int i = 0; i < m; i++) {
		scanf("%d %d", &s, &e);
		a->mat[s][e] = 1;
		a->mat[e][s] = 1;
	}
	printf("边输入完成;共%d条\n", a->arcnum);
	return 0;
}
void Cal(Graph* a) {
	for (int i = 1; i <= a->vexnum; i++) {
		result[cunt][i] = BFS(a, i);
	}
	printf("\nSuccess!\n");
	cunt++;
}
//主函数部分 
int main() {
	int flag = 0;
	Graph* a = (Graph*)malloc(sizeof(Graph));
	cunt = 0;
	/* printf("多组数据,每组数据 m+1 行。第一行有两个数字 n 和 m,代表有 n 个人和m 组朋友关系。\nn 个人的编号为 1 到 n。\n第二行到第 m+1 行每行包括两个数字 a和 b,代表这两个人互相认识。\n当 n 和 m 都等于 0 时,输入结束。");*/
	while (1) {
		//初始化
		Init(a);
	/*	printf("\n                  =================|    -FZC-    |===============                 \n\n");*/
		//读取数据
		flag = Read(a);
		if (flag == 1) {
			show();				//输出结果
			break;
		}
		//处理数据
		Cal(a);
	}
	printf("程序结束!\n");
	return 0;
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值