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