本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师、何钦铭老师的《数据结构》
题目:
六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。
图1 六度空间示意图
“六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。
假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。
输入格式:
输入第1行给出两个正整数,分别表示社交网络图的结点数NNN(1<N≤1041<N\le 10^41<N≤104,表示人数)、边数MMM(≤33×N\le 33\times N≤33×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 }