下面的程序可以用来创建有向图,有向网,无向图,无向网。对于图来说如果来个顶点之间存在边,则在矩阵中用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;
}