大话数据结构——图论全复习~两种存储结构,两种遍历方法,最小生成树,最短路径~2020.7.18

本文详细介绍了图的两种存储结构——邻接矩阵和邻接表,包括它们的概念和实现代码。接着讨论了深度优先遍历和广度优先遍历两种图遍历方法。此外,还讲解了如何找到图的最小生成树,分别通过Prim和Kruscal算法实现。最后,探讨了最短路径问题,提到了Dijkstra算法和Floyd算法。这些内容涵盖了图论的基础知识和应用。
摘要由CSDN通过智能技术生成

存储结构

①图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息(数组下标代表顶点序号),一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。下图更便于大家理解邻接矩阵的概念。
在这里插入图片描述
(注:度的概念指有几条边与顶点相连,当然度也是之于顶点才有意义的。有向图讲究入度与出度,所谓入度,是指有几条边以该顶点为起点,出度同理)
邻接矩阵实现代码:

#include <iostream>
using namespace std;
typedef int VertexesType; 
typedef int EdgeType;
const int MAXVEX = 105;
const int INFINITY = 65535;
struct MGraph{
   
 VertexesType vexs[MAXVEX];
 EdgeType arc[MAXVEX][MAXVEX];
 int numVertexes,numEdges;
};//声明图的存储结构
void createMGraph(MGraph *G){
   
 /*建立的是一个无向图,有向图可与之类比*/
 for(int i=0;i<G->numVertexes;i++){
   
  for(int j=0;j<G->numVertexes;j++){
   
   if(i==j){
   
    G->arc[i][j] = 0;//从自己到自己,距离当然是0 
   }
   else G->arc[i][j] = INFINITY;
  }
 }
 /*以上为初始化操作*/
 cout<<"请输入所要建立的图中的顶点个数与边的个数:";
 cin>>G->numVertexes>>G->numEdges;
 cout<<"请输入"<<G->numVertexes<<"个顶点的信息:";
 for(int i=0;i<G->numVertexes;i++){
   
  cin>>G->vexs[i];  
 }
 for(int i=0;i<G->numEdges;i++){
   
  cout<<"构建(vi,vj)两个顶点之间的边Dij,请输入vi,vj,Dij的值:";
  int v,w,d;
  cin>>v>>w>>d;
  G->arc[v][w] = d;
  G->arc[w][v] = G->arc[v][w];//切记,赋值顺序不可调换 
 }
} 

邻接矩阵应当算是图论中非常非常基础的存储结构,因此,学习了图论,至少掌握这一种数据存储结构是很必要的(后面的最小生成树与最短路径也都是由邻接矩阵实现的)。
邻接表
所谓邻接表,即数组与链表相结合的存储方式。
邻接表的处理方式如下:1.图中的每一个顶点都存储在一个一维数组中,当然,顶点也可以用单链表来存储,不过数组更容易读取顶点信息。另外,对于顶点数组,每个数据元素还需要存储指向第一个邻接点的指针,以便于查找该顶点信息。 2.图中每个顶点vi的所有邻接点(所谓邻接点,就是与顶点vi有边相连的点,这些邻接点当然也是顶点,只不过是其他顶点,参照上“1.”,这些顶点当然也被存储在一维数组中,这是相对不好理解的地方)构成一个线性表(此处线性表用链表实现,因为邻接点个数不确定)。无向图称为顶点vi的边表,有向图则称为顶点vi的弧尾出边表。
在这里插入图片描述
**注:**邻接表存储的是直接邻接点,而不储存间接邻接点。如图中v0,其直接邻接点是v1,v2,v3,储存的便是v1,v2,v3,而不是因为从v1或v2可以通往v3,才存储的v3。边表的next指针域存储的后序结点实际上没有与前序顶点没有任何逻辑关系,只是在物理关系上便于才存储与输出,adjvex域也仅仅是存储了邻接点的下标而已。

这样的结构,对于我们获取图中的信息是十分方便的。比如想知道某个顶点的度,就去查找这个顶点边表中结点的个数。判断vi与vj是否存在边,只需查找vi的边表中的adjvex域是否有vj。对于有向图,一般以顶点为弧尾(箭头起点)来存储边表,反过来则称为逆邻接表,在读取入度与出度时很方便。
邻接表实现代码:

#include <iostream>
using namespace std;
typedef int VertexType;
typedef int EdgeType;
const int MAXVEX = 105;
struct EdgeNode{
   //定义边表结构 
 int adjvex;
 EdgeNode *next;
 EdgeType weight;//存储边的权值 
};
typedef struct//定义顶点表(一维数组实现)结构 
{
   
 VertexType data;
 EdgeNode *FirstEdge;//存储边表的第一个结点,便于读取 
}AdjList[MAXVEX],VertexNode;//用typedef为顶点表定义两种名称
struct GraphAdjList{
   
 AdjList adjList;
 int numVertexes,numEdges;
}MGraph;
void CreateGraphAdjList(GraphAdjList *G){
   
 EdgeNode *e;
 cout<<"输入顶点数与边数:";
 cin>>G->numVertexes>>G->numEdges;
 cout<<"输入"<<G->numVertexes<<"个顶点的信息:";
 for(int i=0;i<G->numVertexes;i++){
   
  cin>>G->adjList[i].data;
  G->adjList[i].FirstEdge=NULL;
 }/*以上为初始化操作,以下为建立邻接表操作*/
 for(int k=0,i,j,d;k<G->numVertexes;k++){
   
  cout<<"建立(vi,vj)间的边Dij,输入vi,vj与Dij的信息:";
  cin>>i>>j>>d;
  e=new EdgeNode;//将边表结点插入边表当中,此处的插入方法为头插法 
  e->adjvex = j; 
  e->next = G->adjList[i].FirstEdge;/*将e之中呢指向当前顶点指向的结点*/
  G->adjList[i].FirstEdge=e;/*将当前顶点的种子很指向e*/
  e=new EdgeNode;
  e->adjvex = i;/*无向图,故正反都需要录入顶点表*/
  e->next=G->adjList[j]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值