#include <iostream>
#include <fstream>
using namespace std;
#define MVNum 10//最大顶点数
#define MAXQSIZE 100//最大队列长度
typedef char VerTexType;//顶点的数据类型为字符型
typedef int ArcType;//边的权值类型为整型
//图的邻接矩阵
typedef struct{
VerTexType vexs[MVNum];//顶点表
ArcType arcs[MVNum][MVNum];//邻接矩阵
int vexnum,arcnum;//图的点数和边数
}Graph;
bool visited[MVNum];//访问标志数组,其初值为"false"
//循环队列
typedef struct{
int *base;//初始化的动态分配存储空间
int front;//头索引,若队列不空,指向队头元素
int rear;//尾索引,若队列不空,指向队尾元素的下一个位置
}sqQueue;
//构造一个空队列Q
void InitQueue(sqQueue &Q){
Q.base = new ArcType[MAXQSIZE];
if(!Q.base) exit(1);
Q.front = Q.rear = 0;
}
//插入元素e为Q的新的队尾元素
void EnQueue(sqQueue &Q, int e){
if((Q.rear + 1) % MAXQSIZE == Q.front)
return;
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXQSIZE;
}
//判断是否为空队
bool QueueEmpty(sqQueue Q){
if(Q.rear == Q.front) return true;
return false;
}
//队头元素出队并置为u
void DeQueue(sqQueue &Q, int &u){
u = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE;
}
//返回值为v的顶点在vexs中的下标
//如果不存在,返回-1
int LocateVex(Graph G , VerTexType v);
//采用邻接矩阵表示法,创建无向图G
void CreateUDN(Graph &G,ifstream &in);
//返回v的第一个邻接点所对应的下标
//如果v没有邻接点,返回-1
int FirstAdjVex(Graph G , int v);
//返回v相对于w的下一个邻接点的下标
//如果没有,返回-1
int NextAdjVex(Graph G , int v , int w);
//从第v个顶点出发,深度优先遍历无向连通图G
void DFS(Graph G, int v);
//对无向图G做深度优先遍历
void DFSTraverse(Graph G);
//从第v个顶点出发,广度优先遍历无向连通图G
void BFS (Graph G, int v);
//对无向图G做广度优先遍历
void BFSTraverse(Graph G);
void showUDN(Graph G);
void showVISITED(Graph G);
int main(){
ifstream in("graph.txt");
int num=0;//测试数据组数
in>>num;
while(num>0)
{
Graph G;
CreateUDN(G,in);
printf("\n---BFSTraverse--");
BFSTraverse(G);
printf("\n--DFSTraverse--");
DFSTraverse(G);
//showUDN(G);
cout<<endl;
num--;
}
in.close();
//BFS
return 0;
}
void showUDN(Graph G)
{
int i , j , k;
for(i = 0; i < G.vexnum; ++i)
{
for(j = 0; j < G.vexnum; ++j)
printf("%d\t",G.arcs[j][i]);//printf("G.arcs[%d][%d]=%d\t",i,j,G.arcs[j][i]);
printf("\n");
}
}
//返回值为v的顶点在vexs中的下标
//如果不存在,返回-1
int LocateVex(Graph G , VerTexType v){
for(int i = 0; i < G.vexnum; ++i)
if(G.vexs[i] == v)
return i;
return -1;
}
//采用邻接矩阵表示法,创建无向图G
void CreateUDN(Graph &G,ifstream &in){
int i , j , k;
VerTexType v1 , v2;
in>>G.vexnum >> G.arcnum;
for(i = 0; i < G.vexnum; ++i)
in >> G.vexs[i];
for(i = 0; i < G.vexnum; ++i)
for(j = 0; j < G.vexnum; ++j)
G.arcs[i][j] = 0;
for(k = 0; k < G.arcnum;++k){
in >> v1 >> v2;
i = LocateVex(G, v1);
j = LocateVex(G, v2);
G.arcs[j][i] = G.arcs[i][j] = 1;
}
}
//返回v的第一个邻接点所对应的下标
//如果v没有邻接点,返回-1
int FirstAdjVex(Graph G , int v){
/*------------代码开始--------------*/
int i;
for(i = 0 ; i < G.vexnum ; ++i)
if(G.arcs[v][i] == 1 && visited[i] == false)
return i;
return -1;
/*------------代码结束--------------*/
}
//返回v相对于w的下一个邻接点的下标
//如果没有,返回-1
int NextAdjVex(Graph G , int v , int w){
/*------------代码开始--------------*/
int i;
for(i = w ; i < G.vexnum ; ++i)
if(G.arcs[v][i] == 1 && visited[i] == false)
return i;
return -1;
/*------------代码结束--------------*/
}
//从第v个顶点出发,深度优先遍历无向连通图G
void DFS(Graph G, int v){
//访问第v个顶点,并置访问标志数组相应分量值为true
//依次检查v的所有邻接点w,如果w未被访问,从w出发进行DFS遍历
/*------------代码开始--------------*/
//访问第v个顶点,并置访问标志数组相应分量值为true
cout << G.vexs[v] << "\t";
visited[v] = true;
//依次检查v的所有邻接点w,如果w未被访问,从w出发进行DFS遍历
int w;
for(w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w))
{
showVISITED(G);
if(!visited[w])
{
DFS(G, w);
}
}
/*------------代码结束--------------*/
}
//对无向图G做深度优先遍历
void DFSTraverse(Graph G){
//访问标志数组初始化
//从第1个未被访问的顶点出发深度优先遍历图G
//如果图G中还有未被访问的结点,重复这一过程,直到图G中所有顶点都被访问为止
/*------------代码开始--------------*/
int v;
for(v = 0; v < G.vexnum; ++v)
visited[v] = false;
//从第1个未被访问的顶点出发深度优先遍历图G
//如果图G中还有未被访问的结点,重复这一过程,直到图G中所有顶点都被访问为止
for(v = 0; v < G.vexnum; ++v)
{
if(!visited[v])
DFS(G, v);
}
/*------------代码结束--------------*/
}
void showVISITED(Graph G)
{
int v;
for(v = 0; v < G.vexnum; ++v)
printf("visited[%d]=%d\t",v,visited[v]);
printf("\n");
}
//从第v个顶点出发,广度优先遍历无向连通图G
void BFS (Graph G, int v){
sqQueue Q;//辅助队列Q
int u;
int w;
//访问第v个顶点,并置访问标志数组相应分量值为true
//辅助队列Q初始化,置空
//v进队
cout << G.vexs[v] << " ";
visited[v] = true;
InitQueue(Q);
EnQueue(Q, v);
//当队列Q不空时重复下列操作:
//队头顶点u出队
//依次检查u的所有邻接点w,如果w未被访问,则访问w,然后将w入队
while(!QueueEmpty(Q)){
DeQueue(Q, u);
for(w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w))
{
showVISITED(G);
if(!visited[w])
{
cout << G.vexs[w] << "\t";
visited[w] = true;
EnQueue(Q, w);
}
}
}
}
//对无向图G做广度优先遍历
void BFSTraverse(Graph G){
//访问标志数组初始化
//从第1个未被访问的顶点出发广度优先遍历图G
//如果图G中还有未被访问的结点,重复这一过程,直到图G中所有顶点都被访问为止
/*------------代码开始--------------*/
int v;
for(v = 0; v < G.vexnum; ++v) visited[v] = false;
//从第1个未被访问的顶点出发广度优先遍历图G
//如果图G中还有未被访问的结点,重复这一过程,直到图G中所有顶点都被访问为止
for(v = 0; v < G.vexnum; ++v)
if(!visited[v])
BFS(G, v);
/*------------代码结束--------------*/
}