一、什么是“图”(Graph)
- 表示“多对多”的关系 
- 包含 - 一组顶点:通常用 V (Vertex) 表示顶点集合 
- 一组边:通常用 E (Edge) 表示边的集合 - 无向边:(v, w) 
- 有向边: 
- 不考虑重边和自回路 
 
 
二、抽象数据类型定义
- 类型名称:图(Graph) 
- 数据对象集:G(V,E)由一个非空的有限顶点集合V和一个有限边集合E组成。 
- 操作集: 
Graph Create();//建立并返回空图;Graph InsertVertex(Graph G, Vertex v);//将v插入G;Graph InsertEdge(Graph G, Edge e);//将e插入G;void DFS(Graph G, Vertex v);//从顶点v出发深度优先遍历图G;void BFS(Graph G, Vertex v);//从顶点v出发宽度优先遍历图G;void ShortestPath(Graph G, Vertex v, int Dist[]);//计算图G中顶点v到任意其他顶点的最短距离;void MST(Graph G);//计算图G的最小生成树;
三、邻接矩阵
- 邻接矩阵G[N][N]——N个顶点从0到N-1编号,若存在边,则 G[i][j] = 1,否则为0。 

- 对于无向图的存储,怎样可以省一半空间? 
- 邻接矩阵 
 用一个长度为N(N+1)/2的1维数组A存储{G00,G10,G11,……,Gn-1,0,…,Gn-1 n-1},则Gij在A中对应的下标是:( i*(i+1)/2 + j )对于网络,只要把G[i][j]的值定义为边j>的权重即可。

- 如,若查看是否有v6到v3的边,则查看G[6*7/2 + 3] = G[24]即可。 
四、邻接矩阵性质
优点:邻接矩阵 —— 有什么好处?
- 直观、简单、好理解 
- 方便检查任意一对顶点间是否存在边 
- 方便找任一顶点的所有“邻接点”(有边直接相连的顶点) 
- 方便计算任一顶点的“度”(从该点发出的边数为“出度”,指向该点的边数为“入度”) - 无向图:对应行(或列)非0元素的个数 
- 有向图:对应行非0元素的个数是“出度”;对应列非0元素的个数是“入度” 
 
缺点:邻接矩阵 —— 有什么不好?
- 浪费空间 —— 存稀疏图(点很多而边很少)有大量无效元素。(对稠密图,特别是完全图,还是很合算的) 
- 浪费时间 —— 统计稀疏图中一共有多少条边 
五、邻接表
G[N]为指针数组,对应矩阵每行一个链表,只存非0元素 。

六、邻接表性质
- 方便找任一顶点的所有“邻接点” 
- 节约稀疏图的空间 - 需要N个头指针 + 2E个结点(每个结点至少2个域) 
 
- 方便计算任一顶点的“度”? - 对无向图:是的 
- 对有向图:只能计算“出度”;需要构造“逆邻接表”(存指向自己的边)来方便计算“入度” 
 
- 方便检查任意一对顶点间是否存在边? - No