图的邻接矩阵表示方法以及遍历

下面的程序可以用来创建有向图,有向网,无向图,无向网。对于图来说如果来个顶点之间存在边,则在矩阵中用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;
} 
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/qq_20916555/article/details/51366219
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞