数据结构与算法(C语言)——图的两种遍历(DFS和BFS)

欢迎阅读 罡罡同学 的文章

(记得点赞关注哈)
还在为代码无法正常运行而烦恼,关注罡罡同学不迷路,解决你的烦恼。
如果你觉得,本文章对你有那么一丢丢的帮助,记得点赞关注转发,罡罡同学非常感谢哈!

后续文章是关于数据结构一些基础实验,本人都已经成功运行,如果有问题,欢迎在评论区留言。

您的支持是罡罡同学前进的最大动力!
(疯狂暗示 点赞 !关注!转发 !!! 点赞 !关注!转发 !!!

关于图的两种遍历(DFS和BFS)代码

废话不多说,直接上代码:
第一种BFS滴:

#include<stdio.h>
#include<stdlib.h>
#define max 20
typedef struct EdgeNode//边表结点 
{   int adjvex;        //存储顶点对应的下标   存储的是一个位置,而非具体元素,为了以后改变数据方便操作 
	struct EdgeNode *next;//链域指向下一个邻接点 
	int weight;      //权值(问题中有权值再用) 
}EdgeNode;
typedef struct VertexNode//顶点表结点 
{	char data;//存放顶点信息 
	EdgeNode *firstedge;//指向边表中第一个结点 
}VertexNode;
typedef struct
{	VertexNode adjlist[max];
	int n,e;
}GraphAdjlist;//声明图的邻接表类型 
int visited[max];//访问标志数组 (访问过赋值为1,反之为0) 

void create(GraphAdjlist *G)//创建邻接表 
{	int i,j,k;
	EdgeNode *e;
	printf("请输入顶点数和边数:");
	scanf("%d%d",&G->n,&G->e);
	getchar();//清除缓冲 
	printf("请输入顶点边号:\n");
	for(i=0;i<G->n;i++)
	{   scanf("%c",&G->adjlist[i].data);//输入顶点编号
		G->adjlist[i].firstedge=NULL;//将边表置空 
		getchar(); 
	}
	for(k=0;k<G->e;k++)
	{   printf("输入边(Vi,Vj)上的顶点序号:\n");
		scanf("%d%d",&i,&j);//头插法方便,快速   如果用尾插法需要指针遍历到尾部,太慢 
		/*使用头插法加入边表结点*/
		e=(EdgeNode *)malloc(sizeof(EdgeNode));
		e->adjvex=j;
		e->next=G->adjlist[i].firstedge; 
		G->adjlist[i].firstedge=e;
		
		e=(EdgeNode *)malloc(sizeof(EdgeNode));//因为是无向图,一条边对应两个顶点 
		e->adjvex=i;
		e->next=G->adjlist[j].firstedge; 
		G->adjlist[j].firstedge=e;	
	 } 
	printf("\n");
}
void BFS(GraphAdjlist *G,int v)
{	EdgeNode *p;
	int queue[max],front=0,rear=0;//定义循环队列并初始化 
	int w,i;
	for(i=0;i<G->n;i++)//标志数组初始化 
	    visited[i]=0;
	printf("%2c",G->adjlist[v].data);
	visited[v]=1;
	rear=(rear+1)%max;
	queue[rear]=v;
	while(front!=rear)
	{	front=(front+1)%max;
		w=queue[front];
		p=G->adjlist[w].firstedge;
		while(p!=NULL)
		{	if(visited[p->adjvex]==0)
			{	printf("%2c",G->adjlist[p->adjvex].data);
				visited[p->adjvex]=1;
				rear=(rear+1)%max;
				queue[rear]=p->adjvex;
			}
			p=p->next;
		}
	}
	printf("\n");
}
int main()
{	GraphAdjlist G;
	create(&G);
	printf("广度优先遍历:");
	BFS(&G,0); 
	return 0;
}

第二种DFS滴:

#include<stdio.h>
#include<stdlib.h>
typedef struct EdgeNode//边表结点 
{   int adjvex;        //存储顶点对应的下标   存储的是一个位置,而非具体元素,为了以后改变数据方便操作 
	struct EdgeNode *next;//链域指向下一个邻接点 
	int weight;      //权值(问题中有权值再用) 
}EdgeNode;
typedef struct VertexNode//顶点表结点 
{	char data;//存放顶点信息 
	EdgeNode *firstedge;//指向边表中第一个结点 
}VertexNode;
typedef struct
{	VertexNode adjlist[20];
	int n,e;
}GraphAdjlist;//声明图的邻接表类型 
int visited[10];//访问标志数组 (访问过赋值为1,反之为0) 

void create(GraphAdjlist *G)//创建邻接表 
{	int i,j,k;
	EdgeNode *e;
	printf("请输入顶点数和边数:");
	scanf("%d%d",&G->n,&G->e);
	getchar();//清除缓冲 
	printf("请输入顶点边号:\n");
	for(i=0;i<G->n;i++)
	{   scanf("%c",&G->adjlist[i].data);//输入顶点编号
		G->adjlist[i].firstedge=NULL;//将边表置空 
		getchar(); 
	}
	for(k=0;k<G->e;k++)
	{   printf("输入边(Vi,Vj)上的顶点序号:\n");
		scanf("%d%d",&i,&j);//头插法方便,快速   如果用尾插法需要指针遍历到尾部,太慢 
		/*使用头插法加入边表结点*/
		e=(EdgeNode *)malloc(sizeof(EdgeNode));
		e->adjvex=j;
		e->next=G->adjlist[i].firstedge; 
		G->adjlist[i].firstedge=e;
		
		e=(EdgeNode *)malloc(sizeof(EdgeNode));//因为是无向图,一条边对应两个顶点 
		e->adjvex=i;
		e->next=G->adjlist[j].firstedge; 
		G->adjlist[j].firstedge=e;	
	 } 
	printf("\n");
}
void DFS(GraphAdjlist *G,int i)
{	EdgeNode *p;
	visited[i]=1;
	printf("%c ",G->adjlist[i].data);
	p=G->adjlist[i].firstedge;
	while(p!=NULL)
	{	if(visited[p->adjvex]==0)
		  DFS(G,p->adjvex);
		p=p->next;
	}
}
void DFSTraverse(GraphAdjlist *G)
{	int i;
	for(i=0;i<G->n;i++)
	  visited[i]=0;
	for(i=0;i<G->n;i++)
	  if(visited[i]==0)
	    DFS(G,i);
}
int main()//A B C D E
{	GraphAdjlist G;
	create(&G);
	printf("深度优先遍历:");
	DFSTraverse(&G);
	return 0;
}

以上就是罡罡同学在学习字符串这一部分,做的实验,供大家参考。
我是罡罡同学,一位初入网安的小白。☜(ˆ▽ˆ)
(疯狂暗示 点赞 !关注!转发 !!! 点赞 !关注!转发 !!!
您的支持是罡罡同学前进的最大动力!

  • 19
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罡罡同学

您的鼓励是罡同学最大的前进动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值