1.元素为字符型的无向图的邻接矩阵
#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define NumVertices 20
#define isLetter(a) ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
bool visited[NumVertices];
int dfn[NumVertices];
using namespace std;
typedef struct
{
char vertex[NumVertices]; //存放图中顶点的数组
int edge[NumVertices][NumVertices]; //存放图中边的数组
int n,e; //图的顶点数和边数
} MTGraph;
/*
* 返回ch在matrix矩阵中的位置
*/
static int get_position(MTGraph g, char ch)
{
int i;
for (i = 0; i<g.n; i++)
if (g.vertex[i] == ch)
return i;
return -1;
}
/*
* 读取一个输入字符
*/
static char read_char()
{
char ch;
do
{
ch = getchar();
}
while (!isLetter(ch));
return ch;
}
//构建无向图
MTGraph* create_graph()
{
char c1, c2;
int v, e;
int i, p1, p2;
MTGraph* pG;
// 输入"顶点数"和"边数"
printf("input vertex number: ");
scanf("%d", &v);
printf("input edge number: ");
scanf("%d", &e);
if (v < 1 || e < 1 || (e >(v * (v - 1))))
{
printf("input error: invalid parameters!\n");
return NULL;
}
if ((pG = (MTGraph*)malloc(sizeof(MTGraph))) == NULL)
return NULL;
memset(pG, 0, sizeof(MTGraph));
// 初始化"顶点数"和"边数"
pG->n = v;
pG->e= e;
// 初始化"顶点"
for (i = 0; i < pG->n; i++)
{
printf("vertex(%d): ", i);
pG->vertex[i] = read_char();
}
// 初始化"边"
for (i = 0; i < pG->e; i++)
{
// 读取边的起始顶点和结束顶点
printf("edge(%d):", i);
c1 = read_char();
c2 = read_char();
p1 = get_position(*pG, c1);
p2 = get_position(*pG, c2);
if (p1 == -1 || p2 == -1)
{
printf("input error: invalid edge!\n");
free(pG);
return NULL;
}
pG->edge[p1][p2] = 1;
pG->edge[p2][p1] = 1;
}
return pG;
}
//深度优先遍历
void DFS(MTGraph G,int i)
{
int j;
cout<< G.vertex[i] <<" ";
visited[i]= true;
for(j = 0; j < G.n ; j++)
{
if ( (G.edge[i][j]==1) && (!visited[j]) )
DFS(G,j);
}
}
void DFSTraverse( MTGraph G)
{
int i;
for(i = 0; i < G.n ; i++)
visited[i] = false;
for(i = 0; i < G.n ; i++)
if(!visited[i]) DFS(G,i);
}
//广度优先遍历
void BFS(MTGraph G,int i)
{
queue <char> q;
int j;
cout<<G.vertex[i]<<" ";
visited[i]= true;
q.push(i);
while(!q.empty())
{
i = q.front();
q.pop();
for(j = 0; j < G.n ; j++)
{
if ( (G.edge[i][j]==1) && (!visited[j]) )
{
cout<<G.vertex[j]<<" ";
visited[j]= true;
q.push(j);
}
}
}
}
void BFSTraverse(MTGraph G)
{
int i;
for(i = 0; i < G.n ; i++)
visited[i] = false;
for(i = 0; i < G.n ; i++)
if(!visited[i]) BFS(G,i);
}
//打印邻接矩阵
void print_graph(MTGraph G)
{
int i, j;
printf("Martix Graph:\n");
for (i = 0; i < G.n; i++)
{
for (j = 0; j < G.n; j++)
printf("%d ", G.edge[i][j]);
printf("\n");
}
}
int main()
{
MTGraph* G;
G = create_graph();
print_graph(*G);
cout<<"深度优先遍历:";
DFSTraverse(*G);
cout<<endl;
cout<<"广度优先遍历:";
BFSTraverse(*G);
}
结果显示:
解析:
图G1包含了"A,B,C,D,E,F,G"共7个顶点,而且包含了"(A,C),(A,D),(A,F),(B,C),(C,D),(E,G),(F,G)"共7条边。由于这是无向图,所以边(A,C)和边(C,A)是同一条边;这里列举边时,是按照字母先后顺序列举的。
(1)对图G1进行深度优先遍历,从顶点A开始。
第1步:访问A。
第2步:访问(A的邻接点)C。
在第1步访问A之后,接下来应该访问的是A的邻接点,即"C,D,F"中的一个。但在本文的实现中,顶点ABCDEFG是按照顺序存储,C在"D和F"的前面,因此,先访问C。
第3步:访问(C的邻接点)B。
在第2步访问C之后,接下来应该访问C的邻接点,即"B和D"中一个(A已经被访问过,就不算在内)。而由于B在D之前,先访问B。
第4步:访问(C的邻接点)D。
在第3步访问了C的邻接点B之后,B没有未被访问的邻接点;因此,返回到访问C的另一个邻接点D。
第5步:访问(A的邻接点)F。
前面已经访问了A,并且访问完了"A的邻接点B的所有邻接点(包括递归的邻接点在内)";因此,此时返回到访问A的另一个邻接点F。
第6步:访问(F的邻接点)G。
第7步:访问(G的邻接点)E。
因此访问顺序是:A -> C -> B -> D -> F -> G -> E
(2)图G1进行广度优先搜索。
第1步:访问A。
第2步:依次访问C,D,F。
在访问了A之后,接下来访问A的邻接点。前面已经说过,在本文实现中,顶点ABCDEFG按照顺序存储的,C在"D和F"的前面,因此,先访问C。再访问完C之后,再依次访问D,F。
第3步:依次访问B,G。
在第2步访问完C,D,F之后,再依次访问它们的邻接点。首先访问C的邻接点B,再访问F的邻接点G。
第4步:访问E。
在第3步访问完B,G之后,再依次访问它们的邻接点。只有G有邻接点E,因此访问G的邻接点E。
因此访问顺序是:A -> C -> D -> F -> B -> G -> E
上面解析转载自http://www.cnblogs.com/skywang12345/,若想了解更多关于图的遍历,可以访问此网站。
2. 元素为int型的无向图的邻接矩阵
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxsize=10; //图中最多顶点个数
using namespace std;
int vis[10];
template<class DataType>
class MGraph
{
private:
DataType vertex[maxsize]; //存放图中顶点的数组
int arc[maxsize][maxsize]; //存放图中边的数组
int vertexNum,arcNum; //图的顶点数和边数
public:
MGraph(DataType a[],int n,int e); //构造函数,建立具有n个顶点e条边的图
~MGraph() {}
void DFS(int v); //深度优先遍历图
void BFS(int v); //广度优先遍历图
void print(MGraph *G); //打印邻接矩阵
};
template<class DataType>
MGraph<DataType>::MGraph(DataType a[],int n,int e)
{
vertexNum=n;
arcNum=e;
for(int i=0; i<vertexNum; i++)
vertex[i]=a[i];
for(int i=0; i<vertexNum; i++) //初始化邻接矩阵
for(int j=0; j<vertexNum; j++)
arc[i][j]=0;
for(int k=0; k<arcNum; k++) //依次输入每一条边
{
int x,y;
cout<<"请输入每条边的起始点和结束点"<<endl;
cin>>x>>y; //输入边依附的两个顶点的编号
arc[x][y]=arc[y][x]=1; //置有边标志
}
}
template<class DataType>
void MGraph<DataType>::DFS(int v)
{
cout<<vertex[v]<<" ";
vis[v]=1;
for(int j=0; j<vertexNum; j++)
if(arc[v][j]==1&&vis[j]==0)
DFS(j);
}
template<class DataType>
void MGraph<DataType>::BFS(int v)
{
int front=-1; //初始化队列,假设队列采用顺序存储并且不会发生溢出
int rear=-1;
int q[20];
cout<<vertex[v]<<" ";
vis[v]=1;
q[++rear]=v; //被访问的顶点入队
while(front!=rear)
{
v=q[++front]; //将队头元素出队并送到v中
for(int j=0; j<vertexNum; j++)
{
if(arc[v][j]==1&&!vis[j])
{
cout<<vertex[j]<<" ";
vis[j]=1;
q[++rear]=j;
}
}
}
}
template<class DataType>
void MGraph<DataType>::print(MGraph *G)
{
int i,j;
for( i=0 ; i< G->vertexNum ; i++)
{
for(j=0; j < G->vertexNum ; j++)
{
cout<<G->arc[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int a[20];
for(int i=0; i<6; i++)
a[i]=i;
MGraph<int> mg(a,5 ,6);
cout<<"邻接矩阵为:"<<endl;
mg.print(&mg);
cout<< "深度优先遍历为:";
memset(vis,0,sizeof(vis));
mg.DFS(0);
cout<<endl;
cout<<"广度优先遍历为:";
memset(vis,0,sizeof(vis));
mg.BFS(0);
}
结果显示:
或者看博客https://blog.youkuaiyun.com/RRWJ__/article/details/81058113