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

题目:

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

Six Degree of Separation
图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

相关文章:

  • 2022-12-23
  • 2021-11-21
  • 2022-12-23
  • 2021-06-10
  • 2022-12-23
  • 2021-10-02
  • 2022-01-21
猜你喜欢
  • 2021-12-18
  • 2022-03-09
  • 2021-10-30
  • 2022-12-23
  • 2022-12-23
  • 2021-07-05
  • 2021-04-30
相关资源
相似解决方案