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

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

图的邻接矩阵表示方法以及遍历的相关文章

数据结构中图的邻接矩阵表示方法

#include<iostream> using namespace std; typedef char vertextype; typedef int edgetype; #define maxvex 100 #define infinity 1000 class MGraph{ public: vertextype vexs[maxvex]; edgetype arc[maxvex][maxvex]; int numvertexs,numedges;//图的顶点数目和图的边的数目 MGra

数据结构(C实现)------- 图的邻接矩阵表示

[本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020] 图的邻接表表示法类似于树的孩子链表表示法,就是对图中的每个顶点vi,将所有邻接于vi的顶点链接成一个单链表,这个单链表就称为顶点vi的邻接表.在邻接表中有两种结点结构:头结点(vexdata,firstarc).表结点(adjvex,nextarc). 其中,表头结点由顶点域(vexdata)和指向第一条邻接边的指针域(firstarc)构成:表结点由邻接点域(adjvex

看数据结构写代码(35) 图的邻接矩阵表示法

杂谈:最近清明小长假,好好的放松了一下.节前 和 节后 都有点 松懈.不好,不好.贵在坚持.加油. 图的邻接矩阵表示法是用 两个数组 来表示 图的数据结构.一个是顶点数组,另一个是邻接矩阵数组.邻接矩阵 里存放着 顶点的关系. 用邻接矩阵表示图,在 看 顶点之间 是否有边,或者 求顶点的度等操作时比较简单.但空间浪费巨大,在插入,删除 顶点 和边 操作时 需要 移动大量数据,造成不便.所以在插入删除比较多,节点数比较多的时候 不宜 使用这种结构. 下面上代码: 源代码网盘地址:点击打开链接 //

图的邻接矩阵表示方式——无权图的最短路径

1 #include<stdio.h> 2 #include<stdlib.h> 3 4 #define OK 1 5 #define NO 0 6 #define TRUE 1 7 #define FALSE 0 8 #define ERROR -1 9 10 #define MaxVerTexNum 100 11 #define INFINITY 65535 12 typedef int ElementType; 13 typedef int Status; 14 typede

浅谈数据结构之图的邻接表深度和广度优先遍历(九)

邻接矩阵是一种不错的图存储结构,但是我们发现,对于边数相对较少的图,这种结构是存在对存储空间的极大浪费的.我们知道,顺序存储结构存在预先分配内存可能造成空间浪费的问题,于是引出了链式存储的结构.同样的,我们也可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题.因此,对于图的存储结构,我们同样引入了一种数组与链表相组合的存储方法,我们一般称之为邻接表. 邻接表的处理方法是这样的:(1).图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易的读取顶点的信息,更加方便:另

图邻接矩阵表示

1.图的邻接矩阵表示法 在图的邻接矩阵表示法中: ① 用邻接矩阵表示顶点间的相邻关系 ② 用一个顺序表来存储顶点信息 2.图的邻接矩阵(Adacency Matrix) 设G=(V,E)是具有n个顶点的图,则G的邻接矩阵是具有如下性质的n阶方阵: [例]下图中无向图G 5 和有向图G 6 的邻接矩阵分别为A l 和A 2 . 3.网络的邻接矩阵 若G是网络,则邻接矩阵可定义为: 其中: w ij 表示边上的权值: ∞表示一个计算机允许的.大于所有边上权值的数. [例]下面带权图的两种邻接矩阵分别

数据结构学习笔记05图 (邻接矩阵 邻接表--&gt;BFS DFS)

数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边<v, w> 表示从v指向w的边(单行线) 不考虑重边和自回路 无向图:边是无向边(v, w) 有向图:边是有向边<v, w> 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的 连通图(Connected Graph):如果对于图的任一两个顶点v.w∈V,v和w都是连通的,则称

图的邻接表表示与无环图的拓扑排序

一.  图的最常用的表示方法是邻接矩阵和邻接表. 1,邻接矩阵 邻接矩阵其实就是一个二维数组,对于每条边<u,v>,我们就令A[u][v] = 1,如果图为有权图,我们也可以令A[u][v]等于该权,这么表示的优点是非常简单,但是它的空间需求很大,如果图是稠密的,邻接矩阵是合适的表示方法,如果图是稀疏的,那这种方法就太浪费空间了,下面给出图的邻接矩阵表示例子. 2 邻接表 邻接表是图的常用储存结构之一.邻接表由表头结点和表结点两部分组成,其中图中每个顶点均对应一个存储在数组中的表头结点.如下图

数据结构 - 图的存储结构表示及其遍历 (DFS &amp;&amp; BFS)

1.邻接矩阵表示的图结构 /* 邻接矩阵表示的图结构 */ #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <queue> #include <stack> using namespace std; typedef char VertexType; //顶点类型应由用户定义 typedef int EdgeType; /