图论基础(图与建图的方式,图的遍历)

文章目录

  • 一、图的基础定义
  • 二、图的存储
  • 三    图的遍历

一、图是什么?

图通常以一个2元组G=<V,E>表示,V表示节点集,E表示边集,|V|表示节点集中元素的个数及节点数,也被称作图的阶,例如在N阶图中有N个节点。|E|表示边集中元素的个数及边数。

若图G中每条边都是没有方向的则称之为无向图,若图G中的每条边都是有方向的则称之为有向图,在无向图中每条边都是有2各节点组成的无序对,例如节点V1和节点V3之间的边记作(v1,v3)或(v3,v1)。在有向图中有向边也被称为弧,每条弧都是有2个节点组成的有序对,例如从节点V1到节点V3的弧记为<v1,v3>,v1被称之为弧尾V3被称为弧头如下图所示,结点的度数与及该节点相关联的边数记作TD(v).

\sum TD(vi)=2e

二、图的存储

图的结构比较复杂,任何2个节点之间都可能有关系,图的存储分为顺序存储和链式存储,顺序存储包括邻接矩阵和边集数组,链式存储包括邻接表,链式向前星,十字链表和邻接多重表。

1.邻接矩阵

邻接矩阵通常采用1个1维数组存储图中节点的信息采用1个2维数组存储图中节点之间的邻接关系。

1. 邻接矩阵的表示方法

(1)无向图的邻接矩阵

在无向图中若从节点为vi到节点vj有边,则邻接矩阵M[i][j]=M[j][i]=1,否则M[i][j]=0.

 无向图邻接矩阵的特点如下

1        无向图的邻接矩阵是对称矩阵,并且是唯一的.

2        第i行或第i列非0元素的个数正好是第i个结点的度,上图中的邻接矩阵第3列非0元素的个数为2说明第3个节点C的度数为2.

(2)有向图的连接矩阵

在有向图中若从节点为vi到节点vj有边,则邻接矩阵M[i][j]=1,否则M[i][j]=0.

(3)网的邻接矩阵

 M[i][j]=w(ij)||无穷大;

2.邻接矩阵的数据结构定义

# define MAXVnum 100
typedef struct{
       char vex[MAXVnum];
       int edge[MAXVnum][MAXVnum];
       int vexnum,edgenum;
}AMGraph;

void CreateAMGraph(AMGraph &G){
    int i,j;
    VexType u,v;
    cout<<"请输入节点数“<<endl;
    cin>>G.vexnum;
    cout<<"请输入边数<<endl;
    cin>>G.edgenum;
    cout<<"请输入节点信细<<;
    for(i=0;i<G.vexnum;i++){
        cin>>G.vex[i];
    }
    for(i=0; i<G.vexnum;i++){
        for(j=0;j<G.vexnum;j++){
        G.Edge[i][j]=0;
        }
     }
    cout<<"请输入每条边依附的两个节点”<<endl;
    while(G.degenum--){
        cin>>u>>v;
        i=locatevex(u);
        j=locatevex(v);
        G.Edge[i][j]=G.Edge[j][i]=1;
    }
    
}

   

2.邻接表(邻接链表)

1.邻接表的表示方法

邻接表是图的一种链式的存储方式其数据结构包括2部分节点和邻接点,

 

 2.邻接表的数据结构定义

typedef struct VexNode{
    VexType data;
    AdjNode *first;    
}VexNode;

typedef struct AdjNode{
    int v;
    struct AdjNode *next;
}AdjNode;

typedef struct{
	VexNode Vex[MAX];
	int vexnum,edgenum;
}ALGraph;
 
void GreateALGraph(AlGraph &G){
	char u,v;
	cout<<"请输入定点属于边数"<<endl;
	cin>>G.vexnum>>G.edgenum;
	cout<<"请输入节点信息"<<endl;
	for(i=1;i<=G.vexnum;i++){
		cin>>G.vex[i].data;
		G.vex[i].first=NULL;
	} 
	cout<<"请输入每条边的两个顶点"<<endl;
	while(G.edgenum--){
		cin>>u>>v;
		int i=locate(u);
		int j=locate(v);
		AdjNode *s;
		s=new AdjNode;
		s->v=j;
		s->next=G.vex[i].first;
		G.vex[i].first=s;
	}
}

 2链式向前星

 数据结构定义

struct node{
	int to,next,w;
}edge[MAXE];

int head[MAX];
int cnt=0;
void add(int u,v,w)
{
	edge[cnt].to=v;
	edge[cut].next=head[u];
	head[u]=cut++;
}
for(i=head[u];i!=-1;i=edge[i].next){
	int v=edge[i].next;
	inw w=edge[i].w;
}

练习1

给定有N个节点M条边的有向图对每个结点V都求A(v),表示从节点V出发能到达的编号的最大的节点. NBA

输入第一行包含2个整数N,M接下来的大M行每行都包括2个整数UV,表示边UV,节点的编号为1到N。

输入样例

4 3

1 2 

2 4 

4 3 

输出样例

4 4 3 4 

 二、图的遍历

1 广度优先遍历

 代码实现

void BFS(AMGraph G,int v){
	int u,v;
	queue<int>q;
	cout<<G.vex[v];
	visited[v]=true;
	q.push(v);
	while(!q.empty()){
		u=q.front();
		q.pop();
		for(i=0;i<G.vexnum;i++){
			if(G.edge[u][i]&&visited[i]){
				cout<<G.vex[i];
				visited[i]=true;
				q.push(i);
			}
		}
	} 
}
void BFS(AMGraph G,int v){
	int u,v;
	AdjNode *p;
	queue<int>q;
	cout<<G.vex[v];
	visited[v]=true;
	q.push(v);
	while(!q.empty()){
		u=q.front();
		q.pop();
		p=G.vex[u].first;
		while(p!=NULL){
			w=p->v;
			if(!visitd[w]){
				cout<<G.vex[w].data;
				visited[w]=true;
				q.push(w);
			}
			p=p->next;
		}
	} 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值