数据结构实验任务七:基于广度优先搜索的六度空间理论验证

问题描述

“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论 可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是 说,最多通过五个人你就能够认识任何一个陌生人。”假如给你一个社交网络图, 请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。 输入要求 多组数据,每组数据 m+1 行。第一行有两个数字 n 和 m,代表有 n 个人和 m 组朋友关系。n 个人的编号为 1 到 n。第二行到第 m+1 行每行包括两个数字 a 和 b,代表这两个人互相认识。当 n 和 m 都等于 0 时,输入结束。 输出要求 每组数据输出 n 行,对每个结点输出与该结点距离不超过 6 的结点数占结点 总数的百分比,精确到小数点后 2 位。每个结节点输出一行,格式为“结点编号:(空 格)百分比%”

运行结果:

代码实现:

#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("[EXP %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;
}
  • 14
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
基于广度优先搜索六度空间理论验证可以采用以下步骤: 1. 定义一个结构体来表示社交网络中的节点,包括节点编号、节点名称、节点的邻居节点等信息。 ``` typedef struct Node { int id; char name[20]; int visited; int num_neighbors; struct Node* neighbors[100]; } Node; ``` 2. 定义一个函数来初始化节点和邻居节点之间的关系。 ``` void init_network(Node* nodes[], int num_nodes) { // 初始化节点 for (int i = 0; i < num_nodes; i++) { nodes[i] = (Node*)malloc(sizeof(Node)); nodes[i]->id = i; sprintf(nodes[i]->name, "Node%d", i); nodes[i]->visited = 0; nodes[i]->num_neighbors = 0; } // 为每个节点添加邻居节点 for (int i = 0; i < num_nodes; i++) { for (int j = 0; j < num_nodes; j++) { if (i != j && rand() % 2 == 1) { nodes[i]->neighbors[nodes[i]->num_neighbors++] = nodes[j]; } } } } ``` 3. 定义一个函数来进行广度优先搜索,查找任意两个节点之间的最短路径长度。 ``` int bfs(Node* start, Node* end) { Queue* queue = create_queue(); enqueue(queue, start); start->visited = 1; int distance = 0; while (!is_empty(queue)) { int size = get_size(queue); for (int i = 0; i < size; i++) { Node* node = dequeue(queue); if (node == end) { return distance; } for (int j = 0; j < node->num_neighbors; j++) { Node* neighbor = node->neighbors[j]; if (!neighbor->visited) { neighbor->visited = 1; enqueue(queue, neighbor); } } } distance++; } return -1; } ``` 4. 定义一个 main 函数来验证六度空间理论。 ``` int main() { srand(time(NULL)); int num_nodes = 100; Node* nodes[num_nodes]; init_network(nodes, num_nodes); int total_distance = 0; for (int i = 0; i < num_nodes; i++) { for (int j = i + 1; j < num_nodes; j++) { int distance = bfs(nodes[i], nodes[j]); total_distance += distance; printf("%s -> %s: %d\n", nodes[i]->name, nodes[j]->name, distance); } } printf("Average distance: %f\n", (float)total_distance / (num_nodes * (num_nodes - 1) / 2)); return 0; } ``` 这个程序会生成一个包含 100 个节点的随机社交网络,并使用广度优先搜索算法来查找任意两个节点之间的最短路径长度。最后,程序会输出所有节点之间的最短路径长度,并计算平均路径长度,以验证六度空间理论的正确性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值