C语言:邻接表建立图并使用BFS算法进行遍历

由于看论文需要,最近自学数据结构到图这一章,用C语言写了一个使用邻接表建立图的程序,最后用BFS算法对顶点进行遍历,DFS较为简单,就不写了。

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100

/*
先定义边,再定义邻接表(结构数组),最后定义图
否则会出现"xxx does not name a type"的错误 
成就:第一个一次性通过的数据结构搭建的程序 
待完成:BFS算法 
*/

typedef int Vertex;
typedef int WeightType;

//定义边 
typedef struct Edge* ENode;
struct Edge{
	Vertex v;
	WeightType weight; 
	ENode next; 
};

//定义邻接表结构数组,每个元素存放着该顶点指向第一条边的指针 
typedef struct EgdeList{
	ENode FirstEgde;	
	//int data; 如果顶点还需要存放数据 
}EgdeList; 

//定义整个图 
typedef struct GNode* LGraph; 
struct GNode{
	int Nv;
	int Ne;
	EgdeList G[MAXSIZE];		//邻接表,一个存储头指针的结构数组 
}; 

//定义组成队列的链表单元结构 
typedef struct QueueNode* Queuelink;
struct QueueNode{
	int v;
	Queuelink next;
};

//定义存放队列两个指针的结构体
typedef struct Queue{
	Queuelink front;
	Queuelink rear;
}Queue;

void init(Queue* PtrQ)
{
	PtrQ->front = PtrQ->rear = (Queuelink)malloc(sizeof(QueueNode));
	PtrQ->front->next = NULL;
} 

void addQ(Queue* PtrQ, int v)
{
	Queuelink p=(Queuelink)malloc(sizeof(QueueNode));
	p->v=v;
	p->next=NULL;
	PtrQ->rear->next=p;
	PtrQ->rear=p;
}

int deleteQ(Queue* PtrQ)
{
	Queuelink FrontCell=PtrQ->front->next;
	PtrQ->front->next=FrontCell->next;
	//删除最后一个元素后,rear将等于NULL,故将其指向头结点(不储值) 
	if(PtrQ->front->next==NULL) PtrQ->rear=PtrQ->front;		 
	int FrontElem=FrontCell->v;
	free(FrontCell);
	return(FrontElem);
}

//初始化图,没有边 
LGraph CreateGraph(LGraph Graph, int VertexNum) 
{
	Graph=(LGraph)malloc(sizeof(struct GNode));
	Graph->Nv=VertexNum;
	Graph->Ne=0; 
	for(Vertex v=0;v<Graph->Nv;v++)
	{
		Graph->G[v].FirstEgde=NULL; 
	} 
	return Graph;
}

//插入边 
LGraph InsertEgde(LGraph Graph,Vertex a,Vertex b,WeightType w)
{
	ENode temp=(ENode)malloc(sizeof(struct Edge));
	temp->next=Graph->G[a].FirstEgde;
	temp->v=b;
	temp->weight=w;
	Graph->G[a].FirstEgde=temp;
	++Graph->Ne;
	return Graph;
} 

//建立图
LGraph BuildGraph(LGraph Graph)
{
	int Nv, Ne;
	Vertex a, b;
	WeightType w;
	printf("请输入图的顶点数:\n");
	scanf("%d",&Nv);
	printf("请输入图的边数:\n");
	scanf("%d",&Ne);
	Graph=CreateGraph(Graph, Nv);
	for(int i=0;i<Ne;i++)
	{
		printf("请输入边的两个顶点及权重,以空格间隔:\n");
		scanf("%d %d %d",&a,&b,&w);
		Graph=InsertEgde(Graph,a,b,w);
	}
	return Graph;
}

//打印图
void PrintGraph(LGraph Graph) 
{
	ENode temp;
	for(int i=0;i<Graph->Nv;i++)
	{
		printf("NO.%d顶点的边为:",i);
		ENode temp=Graph->G[i].FirstEgde;
		while(temp!=NULL)
		{
			printf("%d ",temp->v);
			temp=temp->next;
		}
		printf("\n");
	}
}

void Visit( Vertex V )
{
    printf("正在访问顶点%d\n", V);
}

//BFS算法遍历 
void BFS(LGraph Graph,Vertex a)
{
	printf("现在按BFS算法遍历图的顶点:\n");
	Queue* PtrQ=(Queue*)malloc(sizeof(Queue));
	init(PtrQ);
	int Visited[MAXSIZE]={0};
	int m;
	ENode temp; 
	addQ(PtrQ, a);
	Visit(a);
	Visited[a]=1;
	while(PtrQ->front!=PtrQ->rear)
	{
		m=deleteQ(PtrQ);
		temp=Graph->G[m].FirstEgde;
		while(temp)
		{
			if(Visited[temp->v]!=1)
			{
				addQ(PtrQ,temp->v);
				Visit(temp->v);
				Visited[temp->v]=1;	
			}			
			temp=temp->next;
		}
	}
}

int main()
{
	LGraph Graph=BuildGraph(Graph);
	PrintGraph(Graph); 
	printf("图的边数为:%d\n",Graph->Ne);
	//printf("现插入一条边\n"); 
	//InsertEgde(Graph,2,3,1);
	//PrintGraph(Graph); 
	//printf("图的边数为:%d\n",Graph->Ne);
	BFS(Graph,0);
}

运行结果如下:

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页