如果您对图的定义尚不清楚,可以点此查看关于图的定义和描述。
我们在这里讨论的图的接口有11个,涉及到8个函数接口和3个宏定义。
函数接口包括初始化图、销毁图、插入顶点、插入边、移除顶点、移除边、取出顶点邻接表、判断顶点是否邻接;宏接口包括返回邻接表的结构链表、返回顶点个数、返回边个数。
graph_initvoid graph_init(Graph *graph, int (*match)(const void *key1,const void *key2), void (*destroy)(void *data));
返回值 :无
描述:初始化由参数gragh指定的图。该函数必须在执行其他与图相关的操作之前调用。
match参数指定用来判断两个顶点是否匹配的函数,该函数会用在其他的图操作中。当key1=key2时,match函数返回1;否则返回0。
destroy参数所指定的函数提供一种释放动态分配数据空间的方法。比如,如果图包含由malloc动态分配的空间,则destroy应该设置为free,当销毁图时以此来释放动态分配的内存。对于包含多个动态分配成员的结构化数据,destroy参数应该设置为一个用户定义的析构函数,用来对每一个动态分配的成员以及结构体自身做资源回收操作。如果图不包含需要动态释放空间的数据,destroy参数应该设置为NULL。
复杂度:O(1)
graph_destroyvoid graph_destroy(Graph *graph);
返回值:无
描述:销毁由参数graph所指定的图。该函数调用后,任何其他的图操作都不允许再执行,除非再次初始化。
graph_destroy将图中所有顶点和边都移除,如果destroy参数不为NULL的话,则调用destroy参数所指定的析构函数针对每个移除的顶点和边做资源回收操作。
复杂度:O(V+E),这里V是图中顶点个数,E是边的个数。
graph_ins_vertexint graph_ins_vertex(Graph *graph, const void *data);
返回值:如果插入顶点成功则返回0,如果顶点已经存在则返回1,否则返回-1。
描述:将顶点插入由参数graph所指定的图中。
新顶点包含一个指向data的指针,因此只要顶点还在图中,data所引用的内存就必须保持有效。由调用者管理data所引用的存储空间。
复杂度:O(V),这里V代表图中的顶点个数。
graph_ins_edgeint graph_ins_edge(Graph *graph, const void *data1, const void *data2);
返回值:如果插入边成功,返回0;如果边已经存在,返回1;否则返回-1;
描述:将由data1以及data2所指定的顶点构成的边插入图中。data1和data2必须是使用graph_ins_vertex已经插入图中的顶点。新的边由data1所指定的顶点的邻接表中指向data2的指针来表示。因此,只要这条边还在图中,data2所引用的内存就必须合法。由调用者负责维护data2所引用的内存空间。
要在无向图中插入边(u,v),需要调用该函数两次:第一次将插入由u到v的边,第二次插入由v到u的边。这种类型的表示法对于无向图来说很普遍。
复杂度:O(V),这里V代表图中的顶点个数。
graph_rem_vertexint graph_rem_vertex(Graph *graph,void **data);
返回值:如果移除顶点成功,返回0,否则返回-1。
描述:从graph指定的图中移除与data相匹配的顶点。在调用该函数之前,所有与该顶点相关的边都必须移除。函数返回后,data指向已移除顶点中保存的数据。由调用者负责管理data所引用的存储空间。
复杂度:O(V+E),这里V代表图中顶点个数,而E代表边的个数。
graph_rem_edgeint graph_rem_edge(Graph *graph, const void *data1, void **data2);
返回值:如果移除成功,返回0;否则返回-1。
描述:从graph指定的图中移除从data1到data2的边。函数返回后,data2指向由data1所指定的顶点的邻接表中保存的数据。由调用者管理data2所引用的存储空间。
复杂度:O(V),这里V代表图中的顶点个数。
graph_adjlistint graph_adjlist(const Graph *graph, const void *data, AdjList **adjlist);
返回值:如果取得邻接表成功,返回0;否则返回-1。
描述:取出graph中由data所指定的顶点的邻接表。返回的邻接表以结构体AdjList的形式保存。