采用邻接表存储结构表示图,由顶点集合和边集合构成。
typedef struct EdgeNode //弧节点结构
{
int indx; //点节点集合下标
int weight; //权值
struct EdgeNode *next;
};
typedef struct VertexNode //顶点结构
{
char data;
struct EdgeNode *link;
};
typedef struct Graphics //图结构
{
int Vcount; //顶点数量
int Ecount; //边数量
struct VertexNode *graph[Maxsize];
struct Edges *_edges[Maxsize];
};
Graphics *CreateGraphics()
{
int vcount=0;
int ecount=0;
char str[Maxsize];
int weight=0;
int i,j=-1;
Graphics *gh=(Graphics*)malloc(sizeof(Graphics));
if(NULL==gh)
{
printf("Init Failed.\n");
exit(1);
}
gh->Vcount=0;gh->Ecount=0;
printf("input datas in order:\n");
scanf("%s",str);
i=0;
while(str[i]!='\0')
{
VertexNode *vnode=(VertexNode*)malloc(sizeof(VertexNode));
if(NULL==vnode)
{
printf("Init Failed.\n");
exit(1);
}
vnode->data=str[i];vnode->link=NULL;
gh->graph[vcount]=vnode;
vcount++;
i++;
}
gh->Vcount=vcount;
i=j=-1;
printf("input edges and weight:\n");
scanf("%d,%d,%d",&i,&j,&weight);
while(i!=-1&&j!=-1)
{
EdgeNode *enode=(EdgeNode*)malloc(sizeof(EdgeNode));
if(NULL==enode)
{
printf("Init Failed.\n");
exit(1);
}
//从i到j
enode->indx=j;
enode->next=NULL;
enode->weight=weight;
enode->next=gh->graph[i]->link;
gh->graph[i]->link=enode;
//从j到i
enode=(EdgeNode*)malloc(sizeof(EdgeNode));
if(NULL==enode)
{
printf("Init Failed.\n");
exit(1);
}
enode->indx=i;
enode->next=NULL;
enode->weight=weight;
enode->next=gh->graph[j]->link;
gh->graph[j]->link=enode;
Edges *edge=(Edges*)malloc(sizeof(Edges));
gh->_edges[gh->Ecount]=edge;
gh->_edges[gh->Ecount]->from=i;
gh->_edges[gh->Ecount]->to=j;
gh->_edges[gh->Ecount]->weight=weight;
gh->Ecount++;
scanf("%d,%d,%d",&i,&j,&weight);
}
return gh;
}
深度优先遍历:访问图的某一起始顶点p,然后由该顶点出发,访问其邻接点p1,再从p1出发,访问与p1邻接的点p2,若p2已经被访问,则舍弃继续找下一个与p1相邻接尚未被访问的点;否则由p2出发,进行类似的访问,如此进行下去,直到顶点pn(此时pn的邻接点都已被访问)为止,接着回溯到pn的前一个邻接点,查看是否有其他尚未被访问的顶点,有则访问该点,之后从该点出发,进行上述访问;若无,则继续回溯搜索。重复上述过程,直至图中所有与p连通的点都已被访问到。当然还要考虑,若该图不是连通图,则从图的顶点集合查找第一个未被访问的顶点,此时若存在这样的点,其一定是某一个非连通分量的起始顶点,重复上述过程,直至图中所有顶点都被访问过为止。
采用非递归的方式实现:
void DFS(Graphics *gh)
{
int i=0;
char joined[Maxsize]; //已遍历顶点集合
if(NULL==gh||gh->Vcount==0) return;
TempStack *stack=CreateStack();
for(;i<gh->Vcount||stack->top>=0;)
{
if(stack->top<0)
{
//空栈
bool flag=false;
for(int j=0;j<gh->Vcount&&(!flag);j++)
{
if(i>0)
{
for(int k=0;k<i;k++)
{
if(gh->graph[j]->data!=joined[k])
flag=true;
else
{
flag=false;
break;
}
}
if(flag)
{
joined[i++]=gh->graph[j]->data;
stack->top++;
stack->data[stack->top]=gh->graph[j]->link;
printf("%c\n",joined[i-1]);
break;
}
}
else
{
flag=true;
joined[i++]=gh->graph[0]->data;
stack->data[++stack->top]=gh->graph[0]->link;
printf("%c\n",joined[i-1]);
}
}
}
else
{
//栈不为空
if(stack->data[stack->top]!=NULL)
{
int j=0;
for(;j<i;j++)
{
if(joined[j]==gh->graph[stack->data[stack->top]->indx]->data)
{
EdgeNode *ednode=stack->data[stack->top]->next;
stack->data[++stack->top]=ednode;
break;
}
}
if(j>=i)
{
//尚未加入
joined[i++]=gh->graph[stack->data[stack->top]->indx]->data;
EdgeNode *ednode=gh->graph[stack->data[stack->top]->indx]->link;
stack->data[++stack->top]=ednode;
printf("%c\n",joined[i-1]);
}
}
else
{
//出栈
while(stack->top>0&&stack->data[stack->top-1]->next==stack->data[stack->top])
{
stack->top--;
}
stack->top--;
}
}
}
}
广度优先遍历:从起始点p出发,依次访问p所有未曾访问的邻接点p1,p2,p3...pn,然后顺序的访问p1,p2,p3...pn所有未被访问过的邻接点,再从这些顶点出发,访问他们还未访问过的邻接点,重复上述过程,直至所有顶点都已被访问。有点像二叉树的层序遍历,一层一层的来。
void BFS(Graphics *gh)
{
int i=0;int j=0;
char joined[Maxsize];
if(gh==NULL||gh->Vcount<=0) return;
for(;i<gh->Vcount;)
{
EdgeNode *ednode=gh->graph[i]->link;
j=0;
for(;j<i;j++)
{
if(joined[j]==gh->graph[i]->data)
break;
}
if(j==i)
{
printf("%c\n",gh->graph[i]->data);
joined[i]=gh->graph[i]->data;
i++;
}
while(NULL!=ednode)
{
j=0;
for(;j<i;j++)
{
if(joined[j]==gh->graph[ednode->indx]->data)
break;
}
if(j==i)
{
printf("%c\n",gh->graph[ednode->indx]->data);
joined[i]=gh->graph[ednode->indx]->data;
i++;
}
ednode=ednode->next;
}
}
}