JSMS44-图-深度/广度优先DFS/BFS算法

575 阅读2分钟

这里用的是邻接表表示法,邻接表不清楚的自行百度一下。 先上输出的结果:

graph.PNG

head代表节点,->edge代表head->edge两节点的边,weight代表权重。可以根据图的节点和边的关系画出图的形状。

#include <stdio.h>
#include <stdlib.h>

#define max 100

int visited[max]={0,};

typedef int vex;
typedef struct edge{
	vex vertex;		//对应边
	struct edge *next;//边指向下一个节点
	int weight;			//路径的权重 
}edgenode;

typedef struct vnode{
	edgenode *firstedge;	//指向的第一个节点
	vex head;		//头结点的值 
}Adjlist[max];		//这是一个指针数组,数组里面存的是头结点

typedef struct {
	Adjlist adjlist;
	int nv,ne;
}graph;				//这个是图,里面v,e对应边的数量。adjlist是指针数组


graph *buildGraph()		//创建一个图返回 
{	//用队列来存边a,边b,权重 
	int queue[]={0,1,1,1,2,4,1,4,2,2,4,1,2,5,1,1,3,1,1,7,3,3,5,3,3,6,2,6,7,1,};
	int front=0,rear=sizeof(queue)/sizeof(queue[0]);
	graph *g=(graph *)malloc(sizeof(graph));
	g->ne=10;		//边的个数 
	g->nv=8;		//顶点个数 
	int v1,v2,w;
	for(int v=0;v<g->nv;v++)
	{
		g->adjlist[v].firstedge=NULL;	//图的第一条边都指向NULL 
		g->adjlist[v].head=v;			//图的head都为v,v是0-7,队列中的图的定点也是0-7 
	}
	for(int e=0;e<g->ne;e++)
	{
		v1=queue[front++];	//v1是边a 
		v2=queue[front++];	//v2是边b 
		w=queue[front++];	//w是权重 
		edgenode *e1=(edgenode *)malloc(sizeof(edgenode));	//创建一条边 
		e1->vertex=v1;	//边的vertex=v1 
		e1->weight=w;	//权重 
		e1->next=g->adjlist[v2].firstedge;	//这里是单链表的头插法,把e1插在v2顶点的第一条边上 
		g->adjlist[v2].firstedge=e1;	//这里将v2顶点的第一条边指向e1 
		
		edgenode *e2=(edgenode *)malloc(sizeof(edgenode));  //创建一条边 
		e2->vertex=v2;		//这里和上面一样 
		e2->weight=w;
		e2->next=g->adjlist[v1].firstedge;
		g->adjlist[v1].firstedge=e2;
	}
	return g;
}
void PrintGraph(graph *g)
{
	edgenode *e;
	for(int i=0;i<g->nv;i++)
	{
		printf("H:%d",g->adjlist[i].head);
		for(e=g->adjlist[i].firstedge;e!=NULL;e=e->next)
		{
			printf("E:%d(W:%d)->",e->vertex,e->weight);
		}
		printf("\n");
	}
}

void DFS(graph *g,int v)
{
	edgenode *e;
	visited[v]=1;		//当图的节点被访问了设置为1 
	printf("%d->",g->adjlist[v].head);//输出节点
	for(e=g->adjlist[v].firstedge;e!=NULL;e=e->next)
	{
		if(visited[e->vertex]!=1)	//这里如果e->vertex没有被访问,递归进去访问e->vertex 
		{
			DFS(g,e->vertex);
		}	
	} 
 } 
void BFS(graph *g,int v)
{
	edgenode *e;
	int queue[max];	//创建队列
	int front=0,rear=0;
	visited[v]=8;	//访问节点v
	printf("%d->",g->adjlist[v].head);
	queue[rear++]=g->adjlist[v].head;	//加进队列
	while(front!=rear)
	{
		v=queue[front++];	//出队
		for(e=g->adjlist[v].firstedge;e!=NULL;e=e->next)	//从v开始遍历邻接表后面的节点 
		{
			if(visited[e->vertex]!=8)	//没有访问过 
			{
				visited[e->vertex]=8;	//标记一下访问了 
				printf("%d->",e->vertex);	//访问输出 
				queue[rear++]=e->vertex; 	//加进队列,然后下一轮出队循环 
			 } 
		}	
	} 
	 
} 
 
int main()
{
	graph *g=buildGraph();
	PrintGraph(g);	//打印图 
	int v=0; 
	printf("\n深度优先遍历为:\n");
	DFS(g,v);
	printf("\n广度优先遍历为:\n");
	BFS(g,v);
}