图论(一):图的基本概念+无向图创建和DFS/BFS遍历

本文介绍了图论的基础概念和图的邻接矩阵表示方法,通过C++代码实现了图的创建、深度优先搜索(DFS)和广度优先搜索(BFS)。详细讲解了如何使用邻接矩阵表示无向图,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本日学习了图论的部分内容,了解了图的基本概念及图的矩阵表示方法,先附上笔记。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
图可以用邻接矩阵来进行表示,我们只要在有向图的某个位置进行一条边创建的时候在对称位置也创建一条就能表示无向图了。

实现(C++,泛型):

数据结构设计:

private:
一个储存顶点信息的一维数组
一个储存边信息的二维数组
顶点个数,边的个数
public:
构造/析构函数
创建图的函数
BFS遍历和DFS遍历函数
邻接矩阵打印

定义以及声明:

#include<iostream>
#include<string.h>
const int MAXN = 15;//最大顶点数
int visit[MAXN];//标记数组
template<typename T>
class Graph{
public:
 Graph(T TVertex[],int v,int e):IVertexAmount(v),IEdgeAmount(e)
 {
  for(int i=0;i<IVertexAmount;i++)
  {
   Vertex[i]=TVertex[i];
  }
  CreateGraph();
 }
 int HaveVertex(T temp);
 void CreateGraph();
 void PrintGraph();
 void DFS(int val);
 void BFS(int val);
 ~Graph(){};
private:
 int IVertexAmount;
 int IEdgeAmount;
 T Vertex[MAXN];
 int Matrix[MAXN][MAXN];
};

图的创建

先将矩阵全部清零,然后一个一个边地添加(因为表示的是无向图,所以在其关于主对角线对称的位置也需要添加边)

template<typename T>
void Graph<T>::CreateGraph()
{
 memset(visit,0,sizeof(visit));
 int sign1,sign2;
 for(int i=0;i<IVertexAmount;i++)
 {
  for(int j=0;j<IEdgeAmount;j++)
  {
   Matrix[i][j]=0;
  }
 }
 std::cout<<"all vertexes:";
 for(int m=0;m<IVertexAmount;m++)
 {
  std::cout<<m<<":"<<Vertex[m]<<" ";
 }
 std::cout<<"\n";
 for(int k=0;k<IEdgeAmount;k++)
 {
  std::cout<<"please input vertexes(No.) to add edges"<<std::endl;
  std::cin>>sign1>>sign2;
  if(sign1<IVertexAmount&&sign2<IVertexAmount)
  {
   Matrix[sign1][sign2]++;
   Matrix[sign2][sign1]++;
   std::cout<<"add successful"<<std::endl;
  }
  else
  {
   std::cout<<"Wrong No."<<std::endl;
  }
 }
}

DFS遍历:

从输入的序号开始访问,然后满足条件就递归,标记数组要跟着更新。

template<typename T>
void Graph<T>::DFS(int val)
{
 std::cout<<Vertex[val];
 visit[val]=1;
 for(int i=0;i<IVertexAmount;i++)
 {
  if(!visit[i]&&Matrix[val][i]==1)
  {
   DFS(i);
  }
 }
}

BFS遍历:

先将标记数组清零,然后开一个数组来模拟队列,先将输入的序号入队,然后检查其相邻顶点,有的话就将顶点继续入队访问,访问后标记数组更新,并弹出队首元素,循环直到队列为空(很少用数组来写BFS,卡了很久,以后还是要尝试多种方法,熟能生巧)

template<typename T>
void Graph<T>::BFS(int val)
{
 memset(visit,0,sizeof(visit));
 int Vqueue[MAXN];
 int qfront,qtail,a;
 qfront=-1;
 qtail=-1;
 std::cout<<Vertex[val];
 visit[val]=1;
 Vqueue[++qtail]=val;
 while(qfront!=qtail)
 {
  a=Vqueue[++qfront];
  for(int j=0;j<IVertexAmount;j++)
  {
   if(Matrix[a][j]==1&&visit[j]==0)
   {
    std::cout<<Vertex[j];
    visit[j]=1;
    Vqueue[++qtail]=j;
   }
  }
 }
}

打印:

没什么好说的

template<typename T>
void Graph<T>::PrintGraph()
{
 for(int row=0;row<IVertexAmount;row++)
 {
  for(int col=0;col<IVertexAmount;col++)
  {
   std::cout<<Matrix[row][col]<<" ";
  }
  std::cout<<std::endl;
 }
}

完整代码:

用的DEV写的,有些for循环的变量不太规范,有重名,如果用VS运行最好改一下变量名

#include<iostream>
#include<string.h>
const int MAXN = 15;
int visit[MAXN];
template<typename T>
class Graph{
public:
 Graph(T TVertex[],int v,int e):IVertexAmount(v),IEdgeAmount(e)
 {
  for(int i=0;i<IVertexAmount;i++)
  {
   Vertex[i]=TVertex[i];
  }
  CreateGraph();
 }
 int HaveVertex(T temp);
 void CreateGraph();
 void PrintGraph();
 void DFS(int val);
 void BFS(int val);
 ~Graph(){};
private:
 int IVertexAmount;
 int IEdgeAmount;
 T Vertex[MAXN];
 int Matrix[MAXN][MAXN];
};
template<typename T>
int Graph<T>::HaveVertex(T temp)
{
 for(int i=0;i<IVertexAmount;i++)
 {
  if(temp==Vertex[i])
  {
   return i+1;
  }
 }
 return 0; 
} 
template<typename T>
void Graph<T>::CreateGraph()
{
 memset(visit,0,sizeof(visit));
 int sign1,sign2;
 for(int i=0;i<IVertexAmount;i++)
 {
  for(int j=0;j<IEdgeAmount;j++)
  {
   Matrix[i][j]=0;
  }
 }
 std::cout<<"all vertexes:";
 for(int m=0;m<IVertexAmount;m++)
 {
  std::cout<<m<<":"<<Vertex[m]<<" ";
 }
 std::cout<<"\n";
 for(int k=0;k<IEdgeAmount;k++)
 {
  std::cout<<"please input vertexes(No.) to add edges"<<std::endl;
  std::cin>>sign1>>sign2;
  if(sign1<IVertexAmount&&sign2<IVertexAmount)
  {
   Matrix[sign1][sign2]++;
   Matrix[sign2][sign1]++;
   std::cout<<"add successful"<<std::endl;
  }
  else
  {
   std::cout<<"Wrong No."<<std::endl;
  }
 }
}
template<typename T>
void Graph<T>::PrintGraph()
{
 for(int row=0;row<IVertexAmount;row++)
 {
  for(int col=0;col<IVertexAmount;col++)
  {
   std::cout<<Matrix[row][col]<<" ";
  }
  std::cout<<std::endl;
 }
}
template<typename T>
void Graph<T>::DFS(int val)
{
 std::cout<<Vertex[val];
 visit[val]=1;
 for(int i=0;i<IVertexAmount;i++)
 {
  if(!visit[i]&&Matrix[val][i]==1)
  {
   DFS(i);
  }
 }
}
template<typename T>
void Graph<T>::BFS(int val)
{
 memset(visit,0,sizeof(visit));
 int Vqueue[MAXN];
 int qfront,qtail,a;
 qfront=-1;
 qtail=-1;
 std::cout<<Vertex[val];
 visit[val]=1;
 Vqueue[++qtail]=val;
 while(qfront!=qtail)
 {
  a=Vqueue[++qfront];
  for(int j=0;j<IVertexAmount;j++)
  {
   if(Matrix[a][j]==1&&visit[j]==0)
   {
    std::cout<<Vertex[j];
    visit[j]=1;
    Vqueue[++qtail]=j;
   }
  }
 }
}
int main()
{
 char vex[5]={'A','B','C','D','E'};
 Graph<char> G1(vex,5,5);
 G1.PrintGraph();
 G1.DFS(0);
 std::cout<<"\n";
 G1.BFS(0);
 std::cout<<"\n";
 return 0;
}

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值