图的创建遍历

采用邻接表存储结构表示图,由顶点集合和边集合构成。

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;
		}
	}
}

《图的创建遍历》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/spawn888/article/details/27369651
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞