关于图的一些定义和表示
来源:互联网 发布:淘宝店铺如何转让 编辑:程序博客网 时间:2024/05/02 02:31
一些定义:
一个图(Gragh)G = (V,E)由定点(Vertex)集V和边(Edge)集E组成。
图的每一条边都是由一个对点(v,w)组成的。如果点是有序的,那么图就叫做有向图。
反之则图为无向图。
如果在一个无向图种从每一个顶点到每个其他顶点都存在一条路径,则称该无向图是连通的。具有这样的性质的有向图是强连通的。如果一个有向图不是强连通,但是他的基础图(其弧上去掉方向所形成的图)是连通的,那么该有向图称为弱连通的。
完全图是其每一个顶点间都存在一条边的图。
一条弧两端的两个顶点存在邻接关系
我们可以根据点的邻接关系画出邻接矩阵
那么表示图的第一种方法就是用邻接矩阵来实现。
如图
我们用1来表示两点之前存在关系,用0表示没有关系。
但是如果是带权图,我们可以置他们之间的关系值为权值,而没有邻接关系的两点之间的初始化需要根据实际情况来定。
例如:图代表了飞机的航线,寻找两个城市之间的最短航线。既然是寻找最短,那么我们就应该将没有邻接关系的权设置为∞。那假设是寻找最长的那条航线,我们就应该将其设置为-∞。
这种算法最容易实现方式当然是用二维数组存储。但是假设是一个顶点很多,而边数很少的图,我们需要建立一个v*v大小的图,而大部分的空间都被浪费掉了,如果要进行查找等操作也是及其的不方便,这种图我们称其是稀疏的,显然要存储稀疏图还需要其他的算法。
但是如果是稠密图(边数很多),用这种方式是很方便的。
还是用点的邻接关系来表示图,想到了数组,那很容易就可以想到表了。
直接用链表来动态申请内存不就行了?
用链表来存储不仅可以存储边的权值,还可以方便的找出与其邻接的下一个点,如果用单向链表来表示的话,可想起内存的使用量基本上是双倍的,因为一个结点只能指向下一个结点而不能后退。虽然说指针是一个比较难掌握的东西,但是他确是一个很方便的东西,如果我们在这里使用双向链表或者甚至是循环链表,就可以让空间节省很多,但是这对于指针的掌控要求很高。
所以还需要继续努力啊。
创建一个固定的图的邻接表表示
代码
#include<stdio.h>#include<stdlib.h>typedef struct GraghNode{ int Element; struct GraghNode *next;}Node;typedef struct Gragh{ int EdgeNum = 8; Node *TheCells; }Gragh;Gragh CreatedGragh();void FreeGragh(Gragh G);void PrintfGragh(Gragh G);int main(){ Gragh G; G = CreatedGragh(); PrintfGragh(G); FreeGragh(G);}Gragh CreatedGragh(){ Gragh G; Node *Temp; G.TheCells = (Node*)malloc(sizeof(Node)*G.EdgeNum); if(G.TheCells == NULL) { printf("Out of space!!"); exit(1); } //不用第一个Node,将其置为NULL for(int i = 0; i < G.EdgeNum; i++) { G.TheCells[i].Element = i; G.TheCells[i].next = NULL; } //定义一个固定的图 G.TheCells[1].next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = G.TheCells[1].next; Temp->Element = 2; Temp->next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = Temp->next; Temp->Element = 4; Temp->next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = Temp->next; Temp->Element = 3; Temp->next = NULL; G.TheCells[2].next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = G.TheCells[2].next; Temp->Element = 4; Temp->next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = Temp->next; Temp->Element = 5; Temp->next = NULL; G.TheCells[3].next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = G.TheCells[3].next; Temp->Element = 6; Temp->next = NULL; G.TheCells[4].next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = G.TheCells[4].next; Temp->Element = 6; Temp->next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = Temp->next; Temp->Element = 7; Temp->next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = Temp->next; Temp->Element = 3; Temp->next = NULL; G.TheCells[5].next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = G.TheCells[5].next; Temp->Element = 4; Temp->next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = Temp->next; Temp->Element = 7; Temp->next = NULL; G.TheCells[7].next = (Node*)malloc(sizeof(Node)); if(Temp == NULL) { printf("Error!"); exit(1); } Temp = G.TheCells[7].next; Temp->Element = 6; Temp->next = NULL; return G; }void PrintfGragh(Gragh G){ int i; Node *Temp = NULL; for(i = 1; i < G.EdgeNum; i++) { printf("%-2d| ", G.TheCells[i].Element); //输出头单元 if(G.TheCells[i].next != NULL) { Temp = G.TheCells[i].next; do { printf("%2d", Temp->Element); Temp = Temp->next; }while(Temp!=NULL); } printf("\n-----------------------------\n"); }}void FreeGragh(Gragh G){ int i; Node *Temp = NULL, *Temp1 = NULL; for(i = 0; i < G.EdgeNum; i++) { if(G.TheCells[i].next != NULL) { Temp = G.TheCells[i].next; do { Temp1 = Temp; Temp = Temp->next; free(Temp1); }while(Temp!=NULL); } } free(G.TheCells);}
结果
- 关于图的一些定义和表示
- 图的定义以及表示
- UML中几种类图的定义和表示
- UML中几种类图的定义和表示
- 关于产品定义、架构和设计实现的一些想法
- 关于宏定义的一些使用方法和注意点总结
- 关于特殊二叉树的一些定义
- 关于宏定义的一些理解
- 关于iOS一些常量定义的技巧
- 关于oc定义的一些问题
- 关于指针定义的一些问题
- 关于数据结构的一些名词定义
- 关于GCD的一些宏定义
- 数组的定义格式和数组元素的表示方法
- 关于信息的表示和存储
- 关于程序里的一些基本的“断言”和“序列化”的预处理定义
- 关于二进制补码表示法的一些备忘
- 关于Java中的数据表示的一些讨论
- 多线程之生产者消费者
- 2017.08.21总结
- JVM内存结构
- js 下载服务器上的文件
- 深度学习哪家强?吴恩达、Udacity和Fast.ai的课程我们替你分析好了
- 关于图的一些定义和表示
- 2017.8.21 弦论 思考记录
- 文章标题
- Java GC算法 垃圾收集器
- 传统Servlet获取表单数据
- Java实训第十七天8/18
- 【Java】ThreadLocal
- Unity I2 Localization 插件 含有变量处理办法
- BZOJ 1069 最大土地面积 (围成最大面积 计算几何)