存储结构:
arc[][]存放边,vertex[]存放顶点信息,visited[]作为是否被访问的标志数组
vertexNum存放顶点数,arcNum存放边数
功能:
1.基于邻接矩阵的无向图的构建
2.深度优先遍历
3.广度优先遍历
伪代码:
构建:
1.初始化标志数组
2.输入顶点数、边数、顶点信息、边的信息
3.初始化arc、vertex
深度优先遍历(栈)
1.输出一个顶点v并将其标志为已遍历
2.递归操作
将顶点v与vertexNum个数据尝试,若有边且另一个顶点j未被遍历则深度遍历j
广度优先遍历(队列)
1.初始化队列,front=rear=-1;
2.初始化标志数组
3.输出一个顶点v并将其入队(++rear)
4.重复下列操作直到队列为空
4.1 将队首出队(++front)并赋给v
4.2 将顶点v与vertexNum个数据尝试,若有边且另一个顶点j未被遍历则输出j并将j入队,j标志为已遍历
#include<iostream>
using namespace std;
#define MaxSize 20 //顶点数量最大值
/**基于邻接矩阵的无向图*/
template<class T>
class MGraph
{
public:
MGraph();
~MGraph() {} //析构函数啥也不干
void DFSTraverse();
void BFSTraverse();
private:
T vertex[MaxSize]; //存储顶点信息的数组
int arc[MaxSize][MaxSize]; //存储边的关系的数组
int vertexNum,arcNum; //分别代表顶点的数量和边的数量
int visited[MaxSize];
//DFS要递归,不能初始化visited,那就在对外接口处初始化,内部在实现递归的DFS
void DFS(int v,int visited[]);
};
template<class T>
MGraph<T>::MGraph()
{
int i,j,k;
cout<<"依次输入顶点数n、边数e、及n个顶点的编号和顶点之间的连通关系的两个顶点的编号:"<<endl;
cin>>vertexNum;
cin>>arcNum;
//把标志数组初始化
for(i=0; i<MaxSize; i++)
visited[i]=0;
//顶点赋值
for(i=0; i<vertexNum; i++)
cin>>vertex[i];
//边的关系初始化为0,有关系则赋1(无向)或赋非0值(有向)
//矩阵主对角不为0则需顶点有环,即顶点到顶点
for(i=0; i<vertexNum; i++)
for(j=0; j<vertexNum; j++)
arc[i][j]=0;
//连通关系确认
for(k=0; k<arcNum; k++)
{
cin>>i>>j; //输入连通的两个顶点的下标
arc[i][j]=1;
arc[j][i]=1;
}
}
template<class T>
void MGraph<T>::DFS(int v,int visited[]) //从v开始遍历
{
int j;
cout<<vertex[v]<<' '; //访问顶点,输出数据
visited[v]=1; //该数据访问过后,将其标志
//查找和新的一轮遍历
for(j=0; j<vertexNum; j++)
if(arc[v][j]==1&&visited[j]==0)
DFS(j,visited);
}
template<class T>
void MGraph<T>::DFSTraverse() //从v开始遍历
{
int i,j,v;
//把标志数组初始化
for(i=0; i<MaxSize; i++)
visited[i]=0;
cout<<"深度优先遍历的结果为:";
for(j=0; j<vertexNum; j++)
{
v=vertex[j];
if(visited[v]==0)
DFS(v,visited);
}
cout<<endl;
}
template<class T>
void MGraph<T>::BFSTraverse()
{
T Q[MaxSize];
int front,rear,i,j,v,k;
//把标志数组初始化
for(i=0; i<MaxSize; i++)
visited[i]=0;
front=rear=-1; //初始化队列
cout<<"广度优先遍历的结果为:";
//为了解决防止从一个顶点遍历无法遍历到某个顶点
for(k=0; k<vertexNum; k++)
{
v=vertex[k];
if(visited[v]==0)
{
cout<<vertex[v]<<' ';
visited[v]=1;
Q[++rear]=v; //将下标入队
while(front!=rear) //当队列不为空时
{
v=Q[++front]; //队列头元素出队
for(j=0; j<vertexNum; j++)
if(arc[v][j]==1&&visited[j]==0)
{
cout<<vertex[j]<<' ';
visited[j]=1;
Q[++rear]=j; //一个个的入队,之后会一个个的出队以做到遍历每个节点的链接点
}
}
}
}
cout<<endl;
}
int main()
{
int n,e,i;
int a[MaxSize];
MGraph<int> G;
G.DFSTraverse();
G.BFSTraverse();
return 0;
}
测试数据
输入:
6 5
0 1 2 3 4 5
0 1
0 3
1 2
2 3
4 5
输出:
深度优先遍历的结果为:0 1 2 3 4 5
广度优先遍历的结果为:0 1 3 2 4 5
该图为输入数据的图示