本日学习了图论的部分内容,了解了图的基本概念及图的矩阵表示方法,先附上笔记。
图可以用邻接矩阵来进行表示,我们只要在有向图的某个位置进行一条边创建的时候在对称位置也创建一条就能表示无向图了。
实现(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;
}
结果: