下面的程序可以用来创建有向图,有向网,无向图,无向网。对于图来说如果来个顶点之间存在边,则在矩阵中用1表示,无边则用0表示。在网络中,边是对应权值的。
图的遍历可以分为深度优先遍历和广度优先遍历。
深度优先遍历的思想是,选择某个未被访问的顶点并访问,然后从该顶点出发,选择第一个和该顶点邻接的未被访问的顶点进行访问。在该过程中可以设置一个标识数组flags[]来标识各个顶点是否被访问到。
广度优先搜索的思想是,选择某个未被访问的顶点并访问,然后依次访问该顶点所以的邻接顶点,对于每次被访问的顶点都对其邻接顶点进行一次性访问。这个过程中也要表示顶点被访问的情况。
下面是创建有向图,有向网,无向图,无向网四种邻接矩阵表示方法的程序,包括邻接的深度优先搜索和广度优先搜索:
#include <iostream> #include <limits.h> #include <queue> #include <string.h> using namespace std; #define INFINITY INT_MAX #define MAX_VERTEX_NUM 20 //最大顶点个数 typedef enum {DG, DN, UDG, UDN}GraphKind; //枚举,表示图的种类 typedef int VRType ; typedef char VertexType; //表示顶点关系类型,对无权图用0,1表示顶点是否相邻,如果是有权图则表示权值 typedef struct arccell{ VRType adj; //顶点类型设置为字符类型 char *information; void SetArcCell(VRType vrt, char * infor){ adj = vrt; if(infor != NULL){ information = new char[strlen(infor)+1]; strcpy(information,infor); } } void Init(int madj = INFINITY){ adj = madj; information = NULL; } }ArcCell, AdjMatricx[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct graph{ int vertex_num; //图中顶点的个数 int arc_num; //图中边的条数 AdjMatricx arcs; //邻接矩阵 VertexType vexs[MAX_VERTEX_NUM]; //存储顶点的数组 int kind; }MGraph; bool GetVextex(int &start_vex, int &end_vex, char *tempinfor,MGraph &mg){ //依靠弧的信息得到弧的起点和终点 //创建无向图,无权值,1和0的邻接矩阵 bool first = false; bool second = false; for(int i = 0; i < strlen(tempinfor); i++){ if( tempinfor[i] >= 'A' && tempinfor[i] <= 'Z'){ for(int j = 0; j < mg.vertex_num; j++){ if(tempinfor[i] == mg.vexs[j] && !first){ start_vex = j; first = true; }else if(tempinfor[i] == mg.vexs[j] && !second){ end_vex = j; second = true; } } } } if(first && second) return true; else return false; } void CreateMGraph(MGraph &mg){ //创建无向网Networdk,邻接点之间的弧具有权值 cout<<"input 0 to create directed graph"<<endl; cout<<"input 1 to create directed network(arc has the weight)"<<endl; cout<<"input 2 to create undirected graph"<<endl; cout<<"input 3 to create undirected network"<<endl; cout<<"Please input the kind of graph"<<endl; cin>>mg.kind; cout<<"Please input the the number of the vertexs"<<endl; //输入顶点的个数 cin>>mg.vertex_num; cout<<"Please input the char behalf of these vertexs"<<endl; int i = 0, j; for(; i < mg.vertex_num; i++){ cin>>mg.vexs[i]; } //输入代表顶点的字符 cout<<"Please input the the number of the arcs"<<endl; cin>>mg.arc_num; if(mg.kind == 3 || mg.kind == 1){ //初始化无向网邻接矩阵 和有向网邻接矩阵 for(i = 0; i < mg.vertex_num; i++){ for( j = 0; j < mg.vertex_num; j++){ mg.arcs[i][j].Init(); } } } if(mg.kind == 2 || mg.kind == 0){ //初始化无向图邻接矩阵 或者有向邻接矩阵 for(i = 0; i < mg.vertex_num; i++){ for( j = 0; j < mg.vertex_num; j++){ mg.arcs[i][j].Init(0); } } } char tempinfor[20]; int weight = 0; int start_vex; //起点 int end_vex; //终点 cout<<"Please input the the information of the arcs,first the infor,next is weight"<<endl; for(i = 0; i < mg.arc_num; i++){ //输入弧的信息和权值 cin>>tempinfor; if(mg.kind == 3 || mg.kind == 1){ //如果是无向网则要输入每条边的权值 cin>>weight; }else{ weight = 1; //否则是无向图,则另weight为1 } GetVextex(start_vex,end_vex,tempinfor,mg); //通过输入的弧的信息找出顶点 cout<<"start: "<<start_vex<<" end :"<<end_vex<<endl; mg.arcs[start_vex][end_vex].SetArcCell(weight,tempinfor); //设置邻接矩阵 if(mg.kind == 2 || mg.kind == 3){ mg.arcs[end_vex][start_vex].SetArcCell(weight,tempinfor); //因为是无向图,所以要设置反向边 } } } int FindFirstVertex(const MGraph &mg, int startvex,bool flags[]){ for(int i = 0; i < mg.vertex_num; i++){ if(mg.arcs[startvex][i].adj > 0 && !flags[i]) //找到第一个邻接顶点就返回 return i; } return -1; } void Search(const MGraph &mg, bool flags[], int i,int j){ if(!flags[j] && mg.arcs[i][j].adj > 0) { flags[j] = true; cout<<mg.vexs[j]<<" "; int endvex = FindFirstVertex(mg,j,flags); if(endvex >= 0) Search(mg,flags,j,endvex); } } void DFS(const MGraph &mg){ //深度优先搜索 bool flags[MAX_VERTEX_NUM] = {false}; int i, j; for(i = 0; i < mg.vertex_num; i++){ for(j = 0; j < mg.vertex_num; j++){ if(mg.arcs[i][j].adj > 0 &&!flags[i]){ flags[i] = true; cout<<mg.vexs[i]<<" "; Search(mg,flags,i,j); } } } cout<<endl; } void OutputMGraph(const MGraph * mg){ cout<<"output the mgraph :"<<endl; int i, j; for(i = 0; i < mg->vertex_num; i++){ for(j = 0; j < mg->vertex_num; j++){ if(mg->arcs[i][j].adj == INFINITY){ cout<<" ∞ "; } else{ cout<<" "<<mg->arcs[i][j].adj<<" "; } } cout<<endl; } cout<<endl; } void BFS(const MGraph &mg){ //利用队列实现广度优先搜索 bool flags[MAX_VERTEX_NUM] = {false}; queue<int> mqueue; int i,j,k; for(i = 0; i < mg.vertex_num; i++){ for(j = 0; j < mg.vertex_num; j++){ if(mg.arcs[i][j].adj > 0 &&!flags[i]){ flags[i] = true; mqueue.push(i); while(!mqueue.empty()){ int start = mqueue.front(); mqueue.pop(); cout<<mg.vexs[start]<<" "; for(k = 0; k < mg.vertex_num; k++){ if(mg.arcs[start][k].adj > 0 && flags[k] == false){ flags[k] = true; mqueue.push(k); } } } } } } cout<<endl; } int main(){ MGraph mgraph; CreateMGraph(mgraph); OutputMGraph(&mgraph); cout<<"the depth_first_search: "<<endl; DFS(mgraph); cout<<"the breadth_frist_search: "<<endl; BFS(mgraph); return 0; }
时间: 2024-10-16 20:43:15