图状结构是一种比树形结构更复杂的非线性结构,在图状结构中,任意两个结点之间都可能相关,即结点之间的邻接关系可以是任意的。
图是由非空的顶点集合和一个描述顶点之间关系――边的集合组成.
无向图:顶点之间的连线是没有方向的,则称该图为无向图
有向图:顶点之间的连线是有方向的,则称该图为有向图
无向完全图:在一个无向图中,如果任意两顶点都有一条直接边相连接,则称该图为无向完全图
有向完全图:在一个有向图中,如果任意两顶点之间都有方向互为相反的两条弧相连接,则称该图为有向完全图
常见图的存储结构:
1.邻接矩阵:
一维数组存储顶点信息,矩阵表示各顶点间邻接关系。
n*n的矩阵表示各顶点间连接关系。
A[i][j]表示一维数组中下标为i的元素和j的元素间关系,1或权值表示连接,0或无穷大表示无连接。
优劣势:很容易确定图中两个顶点间是否相连,但是确定有几条边就比价复杂。
2.邻接表:顺序存储与链式存储结合的存储方法,类似于树的孩子链表表示法
当前顶点信息
邻接表
第一个邻接指针
下一个邻接指针
优劣势:当边稀疏时,邻接表表示法节省存储空间。邻接表上容易找到任一顶点的第一个邻接点和下一个邻接点。但要判定任意两个顶点之间是否连接则不及邻接矩阵。
3.十字链表:适用于有向图,实际为邻接表和逆邻接表的结合。
顶点信息:
顶点值域
指向该顶点的第一个顶点信息
该顶点所指向的第一个顶点信息
弧信息:
该弧弧尾顶点信息
该弧弧头顶点信息
弧上信息,如权值
指向相同弧头的下一条弧信息
指向相同弧尾的下一条弧信息
优劣势:既容易找到以vi为尾的弧,也容易找到以vi为头的弧,容易求的顶点出度和入度。
4.邻接多重表:主要用于存储无向图。类似于十字链表示,为解决如在邻接表中标记一个边或删除一条边时的复杂操作
顶点表
顶点值域
第一条依附于该顶点的边信息
边信息:
标记信息,可标记是否被搜索过
该边所依附的两个顶点下标
指向两个顶点其中一个顶点的下一条边的信息
指向两个顶点其中另一个顶点的下一条边的信息
边上信息,如权值
图的遍历:从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次,类似于树的遍历操作。
1.深度优先搜索
使用递归方式搜索。需设置标志数组区分顶点是否已被访问。
2.广度优先搜索
使用辅助队列搜索,同样需要一个标志数组区分顶点是否已被访问。
连通性:通过图的遍历方式来判定是否连通性问题。
无向图连通性:通过一个count值,在搜索到一次连接时count加一,遍历完成后,根据count就可以确定图的连通性。
有向图连通性:可分为弱连通,单侧连通和强连通。
最小生成树:解决连接图中各个顶点的权值和最小的方法。
连通图的一次遍历所经过的边的集合及图中所有顶点的集合就构成了该图的一棵生成树,对连通图的不同遍历,就可能得到不同的生成树,所有生成树中边的权值总和最小的生成树,称为最小生成树。
最小生成树的构造方法:
Prim算法:需设置两个辅助数组,用来保存剩下顶点集合以及已处理顶点与未处理顶点间的最小权值边的权值
思想是依次从已处理过的顶点出发连通未处理过的顶点,将所有连通边中权值最小的选中为最小生成树的边,从而扩展顶点。
(1)原始连通图为G=(V, E),V为所有顶点集合,E为所有边集合
(2)设初始顶点为u1,则设已处理过的顶点集合为U,已包含的边集合为T;初始状态U={u1},T={}
(3)while U != V:
(u,v)=min{wuv;u∈U,v∈V-U } # (依次从U中选择一个顶点,依次从剩下的顶点中处理一点,从E中获取这两点间最小权值)
T=T+{(u,v)} # 将最小权值边加入T,并将对应的未处理顶点加入U已处理集合中
U=U+{v}
(4)直到所有顶点处理完成,结束
Kruskal算法:
思想是从原始连通图的所有边集中依次遍历,从权值最小的边开始,若该边的两个顶点属于同一个连通分量,则舍弃该边,否则将该边加入最小生成树的边集,直至最小生成树的顶点包括原始连通图的所有顶点。
最短路径问题:解决图中任意两点间最小路程方法。
狄克斯特拉算法:设置已处理顶点集合S和未处理顶点集合T,其中T=V-S,V为原始连通图顶点集合。不断计算起始点v0到集合T中各顶点的最小权值和,
1.父-子节点对应表
2.节点花费散列表
3.节点关系散列表
4.已处理节点列表
弗洛伊德算法:
略
有向无环图:与树不同,树的每个子节点只有一个父节点,而有向无环图则是一个子节点可以有N个父节点,只是子节点间隔离不通,不形成环。
应用:
1.含公共子项式的表达式的表示方法,不存在环。
2.AOV网。activity on vertex network。表示项目推进过程中的顺序关系。不允许存在环,一个项目的前决条件不应该是它自己完成为条件。(就是前置条件和后处理过程)
3.拓扑排序。对AOV网络进行拓扑排序。
1).从AOV网络中选择一个i额没有前驱的顶点(入度为0)
2).从AOV网络中删去该顶点,同时删去从该顶点发出的全部有向边。
3).重复步骤2),直到剩余网络中所有顶点都没有前驱。
若最终网中所有顶点均被处理,即均没有前驱,则说明该AOV网络不存在有向回路。
若最终网中仍存在顶点有前驱,则说明该AOV网络存在有向回路。