第六章我们学了图,这一章的内容还是蛮多的。
图分为有向图和无向图,关于它的存储结构,又可以用邻接矩阵和邻接表来存储,它们各有优缺点。
邻接矩阵的存储表示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define MaxInt 32767 //表示极大值 #define MVNum XXX //最大顶点数 typedef XXX VerTexType; typedef XXX ArcType; typedef struct { VerTexType vexs[MVNum];//VerTexType类型的顶点表 ArcType arcs[MVNum][MVNum];//ARCType类型二维数组来存储邻接矩阵 int vexnum,arcsnum; //图的当前顶点数和边数 }AMGraph;
对于邻接矩阵,判断两个顶点之间是否有边,只需要看A[i][j]是否为0,也便于计算各个顶点的度。但
是对它做增加和删除却是要比邻接表要麻烦上许多。
邻接表的存储表示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define MVNum XXX //最大数XXX typedef struct ArcNode //边结点 { int adjvex; //该边所指向的顶点的位置 struct ArcNode *nextarc; //指向下一条边的指针 OtherInfo info; //和边相关的信息 }ARCNode; typedef struct VNode //顶点信息 { VerTexType data; ArcNode *firstarc; //指向第一条依附该顶点的边的指针 }VNode,AdjList[MVNum]; //AdjList表示邻接表类型 typedef struct //邻接表 { AdjList vertices; //这里定义了一个一维数组 int vexnum,arcnum; //图的当前顶点数和边数 }
对于邻接表来说,插入和删除比较方便,可以用头插法也可以用尾插法。但是我在做作业那道题目的时候,
由于题目输出是需要按照从小到大输出,用邻接表就会很不方便,因为还要去判断每一个ArcNode的data值,
然后比较,再按顺序输出。而且也很方便统计边的数目,按照顶点表顺序扫描所以边表就可以得到边的数目。
而且邻接表的空间效率高,所以对于稀疏矩阵来说,邻接表是很不错的选择。但是它也有缺点,不方便判断
顶点之间是否有边,也不方便判断顶点的度。
还有我做题目的时候,也注意到了,无论是邻接表还是邻接矩阵,一定不能忘记给所有的表初始化!!!
学完了图的两种存储结构然后就是学了图的深搜和广搜。每一种存储结构的搜索方式不太一样,但核心思路
是差不多的。由于是遍历一遍,我们需要一个vi数组来记录我们曾经访问过的数据。深搜中我们用到了递归的
算法,而广搜我们用到了队列(就类似于上一节树的层序遍历一样)。具体代码我就不放上来了,书上有,而
且很详细地记了笔记。
接着就是学了最小生成树,有普里姆算法和克鲁斯卡尔算法,前者是选顶点,后者是选边。然后又学了最短
路径,同样有着两种算法,一个是迪杰斯特拉算法,还有一个是佛洛伊德算法(由于博客写的有点仓促,猝不
及防打算过一天再好好研究佛洛伊德算法然后把这几个算法的大致自己写一遍上去。)
emmm不断更新……