图的定义:
图是有顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中G表示一个图,V是图中顶点的集合,E是图中边的集合。
图的分类:
无向图:任意两个顶点之间的边都是无向边,组成的图叫无向图。
无向边:顶点到顶点之间的边没有方向,则称这条边为无向边。
有向图:任意两个顶点之间的边是有向边,组成的图叫有向图。
有向边:顶点到顶点之间的边有方向,则称这条边为有向边。
无向完全图:在无向图中,如果任意两个顶点之间都存在边,则称改图为无向完全图。
含有N个顶点的无向完全图,肯定有(N*(N - 1)) / 2条边。
有向完全图:在有向图中,如果任意两个顶点之间都存在方向互为相反的两条边,则称该图为有向完全图。
连通图:无向图中,任意两个顶点之间都有路径可以到达,说明这个图是连图的,叫做连通图。
强连通图:有向图中,任意两个顶点之间都存在互通的有向路径,则称这个图是强连通图。
连通图的生成树:是一个极小的连通子图,它含有图中全部的N个顶点,但只有足以构成一棵树的N-1条边。(反之不成立,不是有N个顶点和N-1条边就可以构成一个生成树)
有向树:如果一个有向图有一个顶点的入度为0,其余顶点的入度均为1,则是一棵有向树。
入度:以一个顶点为头的边(弧)的数目称为该顶点的入度。(箭头的终点)
出度:以一个顶点为尾的边(弧)的数目称为该顶点的出度。(箭头的起点)
图的存储方式:邻接矩阵和邻接表
邻接矩阵:
一维数组存储顶点信息,二维数组存储边的信息。
如果是带权图,边数组中间填的就是对应边的权值。
邻接表:
邻接表的出现是因为,如果出现的某些图边数相对较少的情况下,使用邻接矩阵存储就会非常占用空间,所以出现了一种链式存储可以节省空间。
顾名思义,邻接表就是有数组和链表组合存储的一种方式。
图的遍历:
1.深度优先搜索遍历(DFS)
类似于二叉树的前序遍历,深入一个方向开始遍历,直到遇到了已经访问过的节点后,开始换一条路径继续搜索。
2.广度优先搜索遍历(BFS)
类似于二叉树的层序遍历,从图中任意节点出发(一般选取根节点),然后将其插入队列中,再从队列中拿出第一个节点,然后将其相邻的节点插入队列中,然后再从队列中取出一个节点,然后将其相邻的节点插入,直到最后队列为空为止。
时间复杂度:对于邻接矩阵而言,时间复杂度是O(N^2),对于邻接表而言,如果出现点多边少的情况,时间复杂度是O(N + e),N是顶点数,e是边数,所以通常情况下,如果出现点多边少的情况,建议使用邻接表来存储。
深度优先搜索和广度优先搜索两种方式,时间复杂度相同,就是思考方式不同而已,所以可根据个人取舍。