邻接矩阵存储图的两种遍历方式

来源:互联网 发布:淘宝联盟返利 编辑:程序博客网 时间:2024/05/29 08:24

下面是用邻接矩阵存储一个无向图的深度优先遍历和广度优先遍历代码,深度优先遍历就是树的先根遍历的一种推广,而广度优先也是和树的层次遍历相似的,用邻接矩阵存储,进行这两种遍历的实现,是比较容易的。

因为用了自己写的循环队列的模版,所以代码看起来有点冗长.

#include<iostream>#include<string>using namespace std;//下面是循环队列模版template<class T>class My_queue;template<class T>class Node{private:T data;Node<T> *next;public:Node(){next=0;}Node(T d){data=d;next=0;}friend My_queue<T>;};template<class T>class My_queue{private:Node<T> *tail;public:My_queue(){tail=new Node<T>();tail->next=tail;}~My_queue(){clean();delete tail;}bool empty(){return (tail->next==tail);}void push(T d){Node<T> *p=new Node<T>(d);p->next=tail->next;tail->next=p;tail=p;}T front(){if(empty()){cout<<"queue is empty!"<<endl;exit(0);}Node<T> *p=tail->next;T data=p->next->data;return data;}T back(){if(empty()){cout<<"queue is empty!"<<endl;exit(0);}T data=tail->data;return data;}void pop(){Node<T> *p=tail->next;Node<T> *q=p->next;p->next=q->next;if(q==tail)tail=p;delete q;}void clean(){Node<T> *p=tail->next;Node<T> *q=p->next;while(q!=p){p->next=q->next;delete q;p->next=q;}}};#define MAX_VERTEX_NUM 20bool visited[20];//全局数组,用于辅助遍历struct MGraph{string vexs[MAX_VERTEX_NUM];//顶点数组int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵int vexnum;//顶点数目int arcnum;//边数目};int Locate_Vex(MGraph G,string x)  //用于确定顶点在顶点数组中的位置{for(int k=0;G.vexs[k]!=x;k++);return k;}void CreateUDN_MG(MGraph &G){//采用邻接矩阵表示法,构造无向图int i,j,k;cout<<"输入图的顶点数和边数:";cin>>G.vexnum>>G.arcnum;cout<<"输入各个顶点的民称:";for(i=0;i<G.vexnum;i++)cin>>G.vexs[i];for(i=0;i<G.vexnum;i++)for(int j=0;j<G.vexnum;j++)G.arcs[i][j]=0;//上面是初始化邻接矩阵for(k=0;k<G.arcnum;k++){cout<<"输入每条边对应的两个顶点:";string v1,v2;cin>>v1>>v2;i=Locate_Vex(G,v1);j=Locate_Vex(G,v2);while(i<0|| i>G.vexnum-1 || j<0 || j>G.vexnum-1){cout<<"结点位置输入错误,重新输入: ";cin>>v1>>v2;i=Locate_Vex(G,v1);j=Locate_Vex(G,v2);}G.arcs[i][j]=1;G.arcs[j][i]=G.arcs[i][j]; //置对称边}cout<<"图构造完成"<<endl;}void DFS(MGraph G,int v){visited[v]=true;cout<<G.vexs[v]<<"  ";for(int j=0;j<G.vexnum;j++)if(G.arcs[v][j] && !visited[j])DFS(G,j);}//深度优先遍历图void DFS_Traverse(MGraph G){//visited数组用来作为是否已访问的标志for(int i=0;i<G.vexnum;i++)visited[i]=false;for(int v=0;v<G.vexnum;v++)if(!visited[v])DFS(G,v);}//广度优先遍历void BFS_Traverse(MGraph G){My_queue<int> q;int u,w,v;for(v=0;v<G.vexnum;v++)visited[v]=false;for(v=0;v<G.vexnum;v++)if(!visited[v]){visited[v]=true;cout<<G.vexs[v]<<"  ";q.push(v);while(!q.empty()){u=q.front();q.pop();for(w=0;w<G.vexnum;w++)if(G.arcs[u][w] && !visited[w]){visited[w]=true;cout<<G.vexs[w]<<"  ";q.push(w);}}}}int main(){MGraph G;CreateUDN_MG(G);cout<<"深度优先遍历图为:";DFS_Traverse(G);cout<<endl;cout<<"广度优先遍历图为:";BFS_Traverse(G);cout<<endl;return 0;}

测试结果:

输入图的顶点数和边数:8 9输入各个顶点的民称:v1 v2 v3 v4 v5 v6 v7 v8输入每条边对应的两个顶点:v1 v2输入每条边对应的两个顶点:v1 v3输入每条边对应的两个顶点:v2 v4输入每条边对应的两个顶点:v2 v5输入每条边对应的两个顶点:v4 v8输入每条边对应的两个顶点:v5 v8输入每条边对应的两个顶点:v3 v6输入每条边对应的两个顶点:v3 v7输入每条边对应的两个顶点:v6 v7图构造完成深度优先遍历图为:v1  v2  v4  v8  v5  v3  v6  v7广度优先遍历图为:v1  v2  v3  v4  v5  v6  v7  v8Press any key to continue

按照上面的输入所生产的图如下所示:


原创粉丝点击