图算法之图的创建
部分整理自:www.cnblogs.com/ahalei/p/3651334.html
像树一样,图也是一种数据组织形式,是一种更加松散的形式,能够更加丰富的表达数据之间的关系(链表、树也是一种图结构)。现实中的很多问题都可以用图来抽象解决,如乘坐地铁,怎样转车才能够使得以最短车程到达目的地,图的最短路径就是该类问题的答案;又比如在多个城市之间铺设光缆,怎样铺设才能让消耗的光缆总长度最小,而图的最小生成树就是该类问题的答案。
一个正权重的有向图如下图,它有5条边(Edge),4个顶点(Vertex)。
图可以以一个二维矩阵(邻接矩阵)的形式存储在内存中,那么该图需要N^2块内存空间,有时候图的二维矩阵是很稀疏(Sparse Matrix),采用邻接表可以克服邻接矩阵内存使用量大的缺点。邻接表其实就是使用链表将顶点及边组织起来,如下图所示:
首先定义边的数据结构,边由到达顶点、到达权重以及指向由同一个顶点出发的下一条边的指针。
typedef struct edge{ int vertex; int weight; struct edge *next; }Edge;
然后定义顶点数组,数组的个数就是顶点的个数,元素就是一个边的指针。那么需要创建图的邻接表,就需要知道顶点个数,以及边的条数。
Edge** createG(int *vertex, int *edge){ int vertexNum, edgeNum; printf("Input number of vertex and dedge: Vertex Edge.\n"); scanf("%d %d",&vertexNum,&edgeNum); Edge** G=(Edge**)malloc(sizeof(Edge*)*vertexNum); int i = 0; for(i = 0; i < vertexNum; i++){ G[i]=NULL; } printf("Input edge data:Vertex Vertex Weight.\n"); for(i = 0; i < edgeNum; i++){ int v1,v2,w; scanf("%d %d %d",&v1,&v2,&w); Edge* e=(Edge*)malloc(sizeof(Edge)); e->next = NULL; e->vertex = v2; e->weight = w; Edge* tmp = G[v1-1]; if(tmp == NULL) G[v1-1] = e; else{ while(tmp->next != NULL) tmp = tmp->next; tmp->next = e; } } *vertex = vertexNum; *edge = edgeNum; return G; }
遍历顶点的边,
void transversalVertex(Edge **G, int vertexNum){ int i = 0; for(i = 0; i < vertexNum; i++){ Edge *tmp = G[i]; printf("%d", i+1); while(tmp != NULL){ printf("----%d--->%d", tmp->weight, tmp->vertex); tmp = tmp->next; } printf("----->NULL\n"); } }
int main(void){ int vertexNum, edgeNum; Edge** G = createG(&vertexNum, &edgeNum); transversalVertex(G, vertexNum); return 0; }
输出:
Input number of vertex and dedge: Vertex Edge. 4 5 Input edge data:Vertex Vertex Weight. 1 3 7 1 4 9 1 2 5 2 4 6 4 3 8 1----7--->3----9--->4----5--->2----->NULL 2----6--->4----->NULL 3----->NULL 4----8--->3----->NULL