注意InsertVertex(插入点函数)返回的是插入后,该点的指针。所以当你的图是空的时候(即Graph==NULL)时,你应该这样子调用该函数:Graph = InsertVertex(x, Graph).否则只有当图非空时,才可以调用。或者你可以为图添加一个表头,或者将Graph定义为全局变量,做一个小小的修改即可。解决方法有很多,不多列举。
像求最短路径,只要用到插入边函数, 这样就不需做修改。因为插入边函数返回插入边之后的新的图。这样子调用插入边函数:Graph = InsertEdge(x, y, Graph).
应用例程,可见算法中的《最短路径:广度优先搜索(C语言实现)》
邻接表:C语言实现
源代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct Ind_Node_tag
{
struct Ind_Node_tag *Next ;
int Number ;
}*Ind_Node ;
/*这是入度结点结构。Number记录该入度点的序号。*/
typedef struct Vertex_tag
{
int Number ;
Ind_Node Indegree ;
struct Vertex_tag *Next ;
}*Vertex ;
/* Number是指该点的序号。如点1,点2.
Indegree 是该点的入度数组
Next 指向下一个点*/
/*FindVertex:
if x in graph
return x
else
return NULL*/
Vertex FindVertex(int x, Vertex Graph)
{
while(Graph != NULL && Graph->Number != x)
Graph = Graph->Next ;
return Graph ;
}
/* InsertVertex:
if x not in graph
insert x into graph
return x
else
return x
*/
Vertex InsertVertex(int x, Vertex Graph)
{
Vertex G ;
if(!(G = FindVertex(x, Graph))) //如果找到了X不做修改,直接返回它,
{ //否则:
G = calloc(1, sizeof(struct Vertex_tag)) ; //分配内存
if(!G) { fprintf(stderr, "Out of memory!\n") ; exit(1) ; } //错误检测
G->Number = x ;
/*如果Graph是NULL的,那么就把G返回。
这就是为什么第一次不能插入点。因为插入点函数返回插入点的指针
如果Graph是全局的,那么可以使用Graph = G解决。使用表头的不解释*/
if(Graph == NULL)
return G ;
/* Graph不为空,那么将点插入到邻接图的最后面*/
while(Graph->Next != NULL)
Graph = Graph->Next ;
Graph->Next = G ;
}
return G ;
/*因此每一次调用该函数后,能够保证该点一定存在于表。
因为如果找到就返回它,不在就插入它 */
}
/* insert x
insert y
update indegree of x */
Vertex InsertEdge(int x, int y, Vertex Graph)
{
Vertex V ;
Ind_Node Ind ;
//Ind将要插入点x的入度结点
Ind = calloc(1, sizeof(struct Ind_Node_tag)) ;
if(!Ind){ fprintf(stderr, "Out of space!\n"); exit(1) ; }
Ind->Number = y ;
//首先,保证x在graph中。
//见InsertVertex注释。调用完插入点函数后,x一定存在于Graph
V = InsertVertex(x, Graph) ;
//如果图是空的即Graph == NULL,时,更新Graph.
//调用这个函数的正确调用方法是Graph = InsertEdge(x, y, Graph)
//这样子如果图是空的,那么就能够更新Graph了。
if(Graph == NULL)
Graph = V ;
//保证y在图中
InsertVertex(y, Graph) ;
//把入度点y插入到x的入度表中。
Ind->Next = V->Indegree ;
V->Indegree = Ind ;
//把Graph返回。
return Graph ;
}
//free memory
//释放内存
void GraphDestory(Vertex Graph)
{
Ind_Node Ind, ITmp ;
Vertex Tmp ;
while(Graph != NULL)
{
Ind = Graph->Indegree ;
while(Ind != NULL)
{
ITmp = Ind ;
Ind = Ind->Next ;
free(ITmp) ;
}
Tmp = Graph ;
Graph = Graph->Next ;
free(Tmp ) ;
}
}
//return how many vertex of graph
//计算图中有多少个点
int SizeOfGraph(Vertex Graph)
{
int Result = 0 ;
while(Graph != NULL)
{
Result ++ ;
Graph = Graph->Next ;
}
return Result ;
}