c语言编程六度空间,7-2 六度空间(30 分)

该博客探讨了六度空间理论,即通过最多五个人就能连接到任何陌生人的概念。它解释了一个用于验证该理论的算法,该算法使用广度优先搜索(BFS)在社交网络图上计算每个节点的六度空间节点数。程序接收社交网络的节点数和边数,然后通过动态分配二维数组来存储图的邻接矩阵。通过对图进行BFS,计算每个节点周围六度空间内的节点比例,并输出结果。
摘要由CSDN通过智能技术生成

7-2 六度空间(30 分)

“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。

d4a90fe4b8aca605f6b87f573d8223fc.png

图1 六度空间示意图

“六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。

假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。

输入格式:

输入第1行给出两个正整数,分别表示社交网络图的结点数N(1

输出格式:

对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:(空格)百分比%”。

输入样例:

10 9

1 2

2 3

3 4

4 5

5 6

6 7

7 8

8 9

9 10

输出样例:

1: 70.00%

2: 80.00%

3: 90.00%

4: 100.00%

5: 100.00%

6: 100.00%

7: 100.00%

8: 90.00%

9: 80.00%

10: 70.00%

#include

#include

#define MAX 10001//最大顶点数

/**

*解题思想:

*对图进行广度搜索

*得出每层中的顶点数

*计算百分比

*/

int BFS(int i, int N, int ** snap)

{// 队列 遍历登记 队头 队尾 计数器 层数

int q[MAX], visit[MAX], front, rear, count, level, last, tail, v, j;

for (j = 0; j < 10001; j++)//初始化数组

visit[j] = 0;

visit[i] = 1;//开始结点

front = rear = -1;//队列初始化

count = 1;//计算六度空间的个数

level = 0;//level计算层数,等于6时跳出

last = i;//last为上一层最后的顶点

q[++rear] = i;//入队 当前顶点所在层数

while (front

{

/*

*图的广度搜索原理解析:

*类似二叉树的层序遍历

*1、从所需要的顶点进入图(类似利用此顶点为树的根结点,构建一棵树)

*2、根结点入队列

*3、寻找与此顶点相连的所有顶点并放入队列中(图的临接矩阵中,储存的是每个顶点间的边的关系,而且无向图的临接矩阵一定为对称矩阵)

*4、当顶点所在行遍历结束,取出队列的下一个顶点,重复。直至遍历所有的顶点

*/

v = q[++front]; //出队

for (j = 1; j <= N; j++)//遍历

if (!visit[j] && snap[v][j] == 1)

{//当结点没有记录而且此处结点为顶点时

q[++rear] = j;//入队列

visit[j] = 1;//记录对应位置

count++;//计数器

tail = j;//tail是当前层的最后一个顶点

}

if (v == last)

{

level++;//层数加一

last = tail;//记录最后一个顶点

}

if (6 == level)//等于六层时,退出循环

break;

}

return count;//返回六度空间内所有顶点数

}

int main(void)

{

int N, M;

int count = 0;

scanf("%d %d", &N, &M);

int **snap;//实现动态分配二维数组

/*注意:

*******动态分配必须按照顺序分配

*******同时数组释放内存的时候要按照先后顺序释放

*******否则会出现野指针

*******内存泄漏导致程序崩溃

*/

snap = (int**)malloc(sizeof(int*) * (N + 1));

if (snap == NULL)

return -1;

//动态分配内存存在失败的可能,所以

//在进行动态分配内存后

//应该进行对应的指针是否为空指针的判断

int i, x, y, j;

for (i = 0; i <= N; i++)

{

*(snap + i) = (int *)malloc(sizeof(int) * (N + 1));

if (*(snap + i) == NULL)

return -1;

}

for (i = 0; i < M; i++)

{

scanf("%d %d", &x, &y);//无向图对角线对称

snap[x][y] = snap[y][x] = 1;//关系对等

}

for (i = 1; i <= N; i++)

{

count = BFS(i, N, snap);

printf("%d: %.2f%%\n", i, (float)count / N * 100);

}

//直接进行头指针的内存释放不全等于所有指针内存的释放

//free(snap);

for (i = 0; i < N; i++)

{

free(*(snap + i));

*(snap + i) = NULL;

}

free(snap);

snap = NULL;

return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值