Six Degree of Separation

本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师、何钦铭老师的《数据结构》

题目:

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


图1 六度空间示意图

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

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

 

输入格式:

输入第1行给出两个正整数,分别表示社交网络图的结点数NNN(1<N≤1041<N\le 10^41<N104​​,表示人数)、边数MMM(≤33×N\le 33\times N33×N,表示社交关系数)。随后的MMM行对应MMM条边,每行给出一对正整数,分别是该条边直接连通的两个结点的编号(节点从1到NNN编号)。

输出格式:

对每个结点输出与该结点距离不超过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%


We use two kinds of method to store the graph:adjacnet matrix and adjacnet table
The code is followed:
  1 /*
  2  * sixDigreeSeparation.c
  3  *
  4  *  Created on: 2017年5月8日
  5  *      Author: ygh
  6  */
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 
 10 /*
 11  * Algorithm thought:
 12  * We easily know this question is BFS.
 13  * we  access the first level nodes, then access second level nodes
 14  * until we reach the sixth level.
 15  * We let every node to BFS until it reach the sixth level,then we record the total nodes M
 16  * it can reach, calculate the M/N(The total point the test data gives) .
 17  */
 18 
 19 #define MAX_VERTEX_MUM 10001
 20 typedef int vertex; /*vertex is the index of point in the graph*/
 21 typedef int dataType; /*dataType is the data type of vertex */
 22 typedef int weightType; /*The data type of weight  */
 23 
 24 /*
 25  * Define a data structure to edge
 26  */
 27 typedef struct eNode *ptrToENode;
 28 typedef struct eNode {
 29     vertex v1, v2;
 30     weightType wight;
 31 };
 32 typedef ptrToENode edge;
 33 
 34 /*
 35  * Define a data structure for adjacent table node
 36  */
 37 typedef struct adjNode *ptrToAdjNode;
 38 typedef struct adjNode {
 39     vertex adjVertex; /*The index of vertex in the graph*/
 40     weightType weight; /*the value of the weight*/
 41     ptrToAdjNode next; /*A point to point next node*/
 42 };
 43 
 44 /*
 45  * Define a data structure for adjacent table head point
 46  */
 47 typedef struct vNode *ptrToVNode;
 48 typedef struct vNode {
 49     dataType data; /*The value of every vertex,some times it will be ignore*/
 50     ptrToAdjNode head;/*The point to point the adjacent table first element*/
 51 } adjList[MAX_VERTEX_MUM];
 52 
 53 /*Define a data structure for graph*/
 54 typedef struct gNode *ptrToGNode;
 55 typedef struct gNode {
 56     int vertex_num;
 57     int edge_num;
 58     adjList g;
 59 };
 60 typedef ptrToGNode adjacentTableGraph; /*a graph show by adjacent table*/
 61 
 62 /*
 63  create a graph given the vertex number.
 64  @param vertexNum The verter number of the graph
 65  @return a graph with vertex but no any egdgs
 66  */
 67 ptrToGNode createGraph(int vertexNum) {
 68     vertex v;
 69     adjacentTableGraph graph = (adjacentTableGraph) malloc(
 70             sizeof(struct gNode));
 71     graph->vertex_num = vertexNum;
 72     graph->edge_num = 0;
 73     for (v = 1; v <= graph->vertex_num; v++) {
 74         graph->g[v].head = NULL;
 75     }
 76     return graph;
 77 }
 78 
 79 /*
 80  insert a edge to graph.We will distinct oriented graph and undirected graph
 81  The e->v1 and e->v2 are the vertexs' indexs in the adjacent table
 82  @param graph The graph you want to insert edge
 83  @param e The edge you want to insert the graph
 84  @param isOriented Whether the graph is oriented graph.If the graph is oriented
 85  we will set adjacent table graph[v1]->head=v2 and set graph[v1].head=v2
 86  otherwise we only set graph[v1].head=v2
 87  */
 88 void insertEdge(adjacentTableGraph graph, edge e, int isOriented) {
 89     ptrToAdjNode newNode;
 90     newNode = (ptrToAdjNode) malloc(sizeof(struct adjNode));
 91     newNode->adjVertex = e->v2;
 92     newNode->weight = e->wight;
 93     newNode->next = graph->g[e->v1].head;
 94     graph->g[e->v1].head = newNode;
 95     if (!isOriented) {
 96         newNode = (ptrToAdjNode) malloc(sizeof(struct adjNode));
 97         newNode->adjVertex = e->v1;
 98         newNode->weight = e->wight;
 99         newNode->next = graph->g[e->v2].head;
100         graph->g[e->v2].head = newNode;
101     }
102 }
103 
104 adjacentTableGraph buildGraph() {
105     adjacentTableGraph graph;
106     edge e;
107     vertex v;
108     int vertex_num;
109     scanf("%d", &vertex_num);
110     graph = createGraph(vertex_num);
111     scanf("%d", &(graph->edge_num));
112     if (graph->edge_num) {
113         e = (edge) malloc(sizeof(struct eNode));
114         for (v = 0; v < graph->edge_num; v++) {
115             scanf("%d %d", &e->v1, &e->v2);
116             e->wight = 1;
117             insertEdge(graph, e, 0);
118         }
119     }
120     return graph;
121 }
122 
123 /*==============================define a queue=====================================================*/
124 /*define a list to store the element in the queue*/
125 typedef vertex elementType;
126 typedef struct node *pList;
127 typedef struct node {
128     elementType element;
129     struct node *next;
130 };
131 
132 /*define a queue to point the list*/
133 typedef struct node2 *pQueue;
134 typedef struct node2 {
135     pList front; /*the front point to point the head of the list*/
136     pList rear; /*the rear point to point the rear of of the list*/
137 };
138 
139 /*create a empty list to store the queue element*/
140 pList createEmptyList() {
141     pList list;
142     list = (pList) malloc(sizeof(struct node));
143     list->next = NULL;
144     return list;
145 }
146 /*create a empty queye*/
147 pQueue createEmptyQueue() {
148     pQueue queue = (pQueue) malloc(sizeof(struct node2));
149     queue->front = NULL;
150     queue->rear = NULL;
151     return queue;
152 }
153 
154 /*
155  Wether the queue is empty
156  @param queue The queue need to adjust
157  @return If the queue is null,return 1 otherwise return 0
158  */
159 int isQueueEmpty(pQueue queue) {
160     return (queue->front == NULL);
161 }
162 
163 /*
164  Add a element to a queue,If the queue is null,we will create a new queue
165  @parama queue The queue we will add elememt to
166  @prama element The element we will add to queue
167  */
168 void addQueue(pQueue queue, elementType element) {
169     if (isQueueEmpty(queue)) {
170         pList list = createEmptyList();
171         list->element = element;
172         queue->front = queue->rear = list;
173     } else {
174         pList newNode = (pList) malloc(sizeof(struct node));
175         newNode->element = element;
176         newNode->next = queue->rear->next;
177         queue->rear->next = newNode;
178         queue->rear = newNode;
179     }
180 }
181 
182 /*
183  delete a element from a queue
184  @param queue The queue will be deleted a element
185  @return The element has been deleted
186  */
187 elementType deleteEleFromQueue(pQueue queue) {
188     if (isQueueEmpty(queue)) {
189         printf("the queue is empty,don't allow to delete elemet from it!");
190     } else {
191         pList oldNode = queue->front;
192         elementType element = oldNode->element;
193         if (queue->front == queue->rear) {
194             queue->rear = queue->front = NULL;
195         } else {
196             queue->front = queue->front->next;
197         }
198         free(oldNode);
199         return element;
200     }
201 }
202 
203 /*
204  * Initialize a visited array that make them all to zero
205  */
206 void initVisited(adjacentTableGraph graph, int *visited) {
207     int i;
208     for (i = 0; i <= graph->vertex_num; i++) {
209         visited[i] = 0;
210     }
211 }
212 
213 /*
214  Breadth first search
215  @param graph The graph stored by the adjacent table
216  @param startPoint The point we start search
217  @param visited A array to tag the elemeent whether has been visited
218  */
219 int BFS(adjacentTableGraph graph, vertex startPoint, int *visited) {
220     ptrToAdjNode p;
221     int count = 0;
222     int level = 0;
223     int last = startPoint, tail;
224     visited[startPoint] = 1;
225     count++;
226     pQueue queue = createEmptyQueue();
227     addQueue(queue, startPoint);
228     while (!isQueueEmpty(queue)) {
229         elementType element = deleteEleFromQueue(queue);
230         for (p = graph->g[element].head; p; p = p->next) {
231             if (visited[p->adjVertex] == 0) {
232                 visited[p->adjVertex] = 1;
233                 addQueue(queue, p->adjVertex);
234                 count++;
235                 tail = p->adjVertex;
236             }
237         }
238         if (last == element) {
239             level++;
240             last = tail;
241         }
242         if (level == 6) {
243             return count;
244         }
245     }
246     return count;
247 }
248 
249 /*
250  *Prove the six degree of separation
251  */
252 void SDS(adjacentTableGraph graph) {
253     vertex v;
254     int count;
255     int visited[graph->vertex_num+1];
256     float result;
257     for (v = 1; v <= graph->vertex_num; v++) {
258         initVisited(graph, visited);
259         count = BFS(graph, v, visited);
260         result = (float)((float)count / graph->vertex_num)*100;
261         printf("%d: %0.2f", v, result);
262         printf("%%");
263         printf("\n");
264     }
265 }
266 
267 int main() {
268     adjacentTableGraph graph = buildGraph();
269     SDS(graph);
270     return 0;
271 }
Adjacnet Table

 

  1 /*
  2  * sixDigreeSeparation.c
  3  *
  4  *  Created on: 2017年5月9日
  5  *      Author: ygh
  6  */
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 
 10 /*
 11  * Algorithm thought:
 12  * We easily know this question is BFS.
 13  * we  access the first level nodes, then access second level nodes
 14  * until we reach the sixth level.
 15  * We let every node to BFS until it reach the sixth level,then we record the total nodes M
 16  * it can reach, calculate the M/N(The total point the test data gives) .
 17  */
 18 
 19 #define MAX_VERTEX_NUM 10001 /*define the max number of the vertex*/
 20 #define INFINITY 65535     /*define double byte no negitive integer max number is 65535*/
 21 
 22 typedef int vertex; /*define the data type of the vertex*/
 23 typedef int weightType; /*define the data type of the weight*/
 24 typedef char dataType; /*define the data type of the vertex value*/
 25 
 26 /*define the data structure of the Edge*/
 27 typedef struct eNode *ptrToENode;
 28 typedef struct eNode {
 29     vertex v1, v2; /*two vertex between the edge <v1,v2>*/
 30     weightType weight; /*the value of the edge's weigth */
 31 };
 32 typedef ptrToENode edge;
 33 
 34 /*define the data structure of the graph*/
 35 typedef struct gNode *ptrToGNode;
 36 typedef struct gNode {
 37     int vertex_number; /*the number of the vertex*/
 38     int edge_nunber; /*the number of the edge*/
 39     weightType g[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; /*define the adjacent matrix of graph*/
 40     dataType data[MAX_VERTEX_NUM]; /*define the dataType array to store the value of vertex*/
 41 };
 42 typedef ptrToGNode adjacentMatrixGraph; /*a graph show by adjacent matrix*/
 43 
 44 /*
 45  create a graph given the vertex number.
 46  @param vertexNum The verter number of the graph
 47  @return a graph with vertex but no any egdgs
 48  */
 49 adjacentMatrixGraph createGraph(int vertexNum) {
 50     vertex v, w;
 51     adjacentMatrixGraph graph;
 52     graph = (adjacentMatrixGraph) malloc(sizeof(struct gNode));
 53     graph->vertex_number = vertexNum;
 54     graph->edge_nunber = 0;
 55     /*initialize the adjacent matrix*/
 56     for (v = 1; v <= graph->vertex_number; v++) {
 57         for (w = 1; w <= graph->vertex_number; w++) {
 58             graph->g[v][w] = 0;
 59         }
 60     }
 61 
 62     return graph;
 63 }
 64 
 65 /*
 66  insert a edge to graph.We will distinct oriented graph and undirected graph
 67  @param graph The graph you want to insert edge
 68  @param e The edge you want to insert the graph
 69  @param isOriented Whether the graph is oriented graph.If the graph is oriented
 70  we will set adjacent matrix [n][m]=[m][n]=edge's weight,else we only set
 71  the adjacent matrix [n][m]=edge's weight
 72  */
 73 void inserEdge(adjacentMatrixGraph graph, edge e, int isOriented) {
 74     graph->g[e->v1][e->v2] = e->weight;
 75     if (!isOriented) {
 76         graph->g[e->v2][e->v1] = e->weight;
 77     }
 78 }
 79 
 80 /*
 81  construct a graph according user's input
 82 
 83  @return a graph has been filled good
 84  */
 85 adjacentMatrixGraph buildGraph() {
 86     adjacentMatrixGraph graph;
 87     edge e;
 88     int vertex_num, i;
 89     scanf("%d", &vertex_num);
 90     graph = createGraph(vertex_num);
 91     scanf("%d", &(graph->edge_nunber));
 92     if (graph->edge_nunber) {
 93         e = (edge) malloc(sizeof(struct eNode));
 94         for (i = 0; i < graph->edge_nunber; i++) {
 95             scanf("%d %d", &e->v1, &e->v2);
 96             e->weight = 1;
 97             inserEdge(graph, e, 0);
 98         }
 99     }
100 
101     return graph;
102 
103 }
104 
105 /*=====================define a queue used BFS================================*/
106 /*
107  * The elementType is element which the following list store.
108  */
109 typedef int elementType;
110 
111 /*
112  * Define a list to store the queue elements
113  */
114 typedef struct node1 *pList;
115 typedef struct node1 {
116     elementType element;
117     struct node1 *next;
118 };
119 
120 /*
121  * Define a queue used to BFS
122  */
123 typedef struct node2 *pQueue;
124 typedef struct node2 {
125     pList font;
126     pList rear;
127 };
128 
129 /*
130  * Create a empty list
131  */
132 pList createEmptyList() {
133     pList list = (pList) malloc(sizeof(struct node1));
134     list->next = NULL;
135     return list;
136 }
137 
138 /*
139  * Create a empty queue
140  */
141 pQueue createEmptyQueue() {
142     pQueue queue = (pQueue) malloc(sizeof(struct node2));
143     queue->font = queue->rear = NULL;
144     return queue;
145 }
146 
147 /*
148  * Whether the queue is empty
149  */
150 int isQueueEmpty(pQueue queue) {
151     return (queue->font == NULL);
152 }
153 
154 /*
155  * Insert a element to a queue
156  */
157 void insertQueue(pQueue queue, elementType element) {
158 
159     if (isQueueEmpty(queue)) {
160         pList list = createEmptyList();
161         list->element = element;
162         queue->font = queue->rear = list;
163     } else {
164         pList newNode = (pList) malloc(sizeof(struct node1));
165         newNode->element = element;
166         //newNode->next = queue->rear->next;
167         queue->rear->next = newNode;
168         queue->rear = newNode;
169     }
170 }
171 
172 elementType deleteElementQueue(pQueue queue) {
173     if (isQueueEmpty(queue)) {
174         return -1;
175     } else {
176         if (queue->font == queue->rear) {
177             pList temp = queue->font;
178             elementType elememt = temp->element;
179             free(temp);
180             queue->font = queue->rear = NULL;
181             return elememt;
182         } else {
183             pList temp = queue->font;
184             elementType elememt = temp->element;
185             free(temp);
186             queue->font = queue->font->next;
187             return elememt;
188         }
189 
190     }
191 
192 }
193 
194 /*
195  *Breath first search a graph which store in form of adjacent matrix
196  *@param graph The graph stored with adjacent matrix
197  *@param startPoint The start point we start search
198  *@param visited A array to tag whether element has been accessed
199  */
200 int BFS(adjacentMatrixGraph graph, vertex startPoint, int *visited) {
201     vertex v, w;
202     /*
203      * count:to record the total nodes the start point can access
204      * level:to record the level the current node accessed
205      * tail:to record the every node's index, every access it will be flush
206      * last:to record last lever latest accessed node,we can use it to
207      *         let level add.
208      */
209     int count = 0;
210     int level = 0, last = startPoint;
211     int tail = last;
212     pQueue queue = createEmptyQueue();
213     count++;
214     visited[startPoint] = 1;
215     insertQueue(queue, startPoint);
216     while (!isQueueEmpty(queue)) {
217         w = deleteElementQueue(queue);
218         for (v = 1; v <= graph->vertex_number; v++) {
219             if (graph->g[w][v] != 0 && visited[v] == 0) {
220                 visited[v] = 1;
221                 insertQueue(queue, v);
222                 tail = v;
223                 count++;
224             }
225         }
226         if (w == last) {
227             level++;
228             last = tail;
229         }
230 
231         if (level == 6) {
232             return count;
233         }
234     }
235     return count;
236 
237 }
238 
239 /*
240  * Initialize a visited array that make them all to zero
241  */
242 void initVisited(adjacentMatrixGraph graph, int *visited) {
243     int i;
244     for (i = 1; i <= graph->vertex_number; i++) {
245         visited[i] = 0;
246     }
247 }
248 
249 /*
250  *Prove the six degree of separation
251  *@param graph A graph prepared
252  */
253 void SDS(adjacentMatrixGraph graph) {
254     int visited[graph->vertex_number + 1];
255     vertex v;
256     int count;
257     float result;
258     for (v = 1; v <= graph->vertex_number; v++) {
259         initVisited(graph, visited);
260         count = BFS(graph, v, visited);
261         result = (float) ((float) count / graph->vertex_number * 100);
262         printf("%d: %0.2f", v, result);
263         printf("%%");
264         printf("\n");
265     }
266 }
267 
268 int main() {
269     adjacentMatrixGraph graph = buildGraph();
270     SDS(graph);
271     return 0;
272 }
Adjacnet Matrix

 

From PTA test result,we find the adjacent matrix effective is more high than adjacent table.But the adjacent matrix take more memory.Is it use space

to swap the time

the test result is follow

 

转载于:https://www.cnblogs.com/yghjava/p/6832602.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值