数据结构和算法-12-图

649 阅读5分钟

一些概念

1. 从数学意义上说,树是图的一种;
2. 图通常有一个固定的形状,这是由物理或抽象问题所决定的;
3. 顶点:在图中,节点通常叫做顶点;
4. 边:连接顶点的线,叫做边;
5. 邻接:若两个顶点被同一条边连接,就称这两个顶点是邻接的;
6. 路径:边的序列;
7. 连通图:若至少有一条路径可以连接起所有顶点,那么这个图就被称作连通的;
8. 非连通图:包含几个连通子图;
9. 无向图:边没有方向,可以从任意一边到另一边;
10. 有向图:边是单向的,如A--->B,只能从A到B,不能从B到A,就如单行道一样;
11. 带权的图:边被赋予一个权值,权值是一个数字,它能代表两个顶点间的物理距离,或者从一个顶点到另一个顶点的时间,或者其他任何衡量标准,如花销等;
12. 不带权的图:边没有权值的图;

表示图的两个方法:

1. 邻接矩阵:一个N*N(N为顶点个数)的二维数组,数据项表示两点间是否存在边,有则1,无则0(或true/false);

2. 邻接表:一个链表数组,每个单独的链表表示了有哪些顶点与当前顶点邻接;

搜索图的两个方法: (最终都会到达所有连通的顶点)
1. 深度优先搜索 DFS,通过栈实现:
规则1:如果可能,访问一个邻接的未访问的顶点,标记它,并把它放入栈中;
规则2:当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点;
规则3:若不能执行规则1和2,则完成了整个搜索过程;
2. 广度优先搜索 BFS , 通过队列实现:
规则1: 访问当前顶点的下一个未访问的邻接点(如果存在),标记为已访问,并把它插入到队列;
规则2: 若由于没有未访问的邻接点而不能执行规则1,则从队列头取一个顶点(如果存在),并使其为当前顶点,继续执行规则1;
规则3: 若由于队列为空而不能执行规则2,则搜索结束;

**最小生成树:
**使用最少数量的边连接所有顶点;

边的数量总比顶点数量小1;

该算法可以基于深度DFS/BFS 实现;

**无权无向图的实现
**1. 图的顶点类

2. 图的实现类中还会用到之前文章提过的栈和队列

- ArrayStack(使用数组的实现栈);

- ArrayQueue(使用数组实现的队列);

3. 无权无向图的实现类

4. 测试无向无权图

**有向图的拓扑排序
**拓扑: 研究几何图形或空间在连续改变形状后还能保持不变的一些性质的一个学科;它只考虑物体间的位置关系而不考虑它们的形状和大小。
拓扑排序: 是可以用图模拟的另一种操作,它可用于表示某些项目或时间必须按特定的顺序排列或发生
步骤:

  1. 找到一个 没有 后继的顶点(若有一条边从A指向B,那么B就是A的后继);

  2. 从图中删除这个顶点,在列表的前面插入顶点的标记;

  3. 重复1,2步骤,直到所有顶点都从图中删除,这时,列表显示的顶点顺序就是拓扑排序的结果 (可以在其他地方存储图的数据,在拓扑排序完成后恢复他们);

拓扑排序必须在 无环的有向图(有向无环图,DAG) 中进行:

1. 环:是一条路径,他的起点和终点都是同一个顶点;
2. 树:不包含环的图叫做树,如前面的二叉树等,都是这个意义上的数;
拓扑排序的结果并不是唯一的,可以通过调整算法得到不同的结果;

**有向图的实现
**1. 图的顶点类

2. 有向图的实现类

3. 测试有向无环图的拓扑排序

**关键路径分析
**用图对工作进度建模(带权图)

**有向图的连通性
**从一个顶点出发,能够到达那些顶点;

注意有向图的边是有方向的;

如何查找连通性:

1. 可以使用上面的DFS算法打印出连通性表;

2. 使用Warshall算法利用图的邻接矩阵求出原图的传递闭包;
可以用于计算邻接矩阵的可达矩阵,详见Matrix.ReachableMatrix.invoke2()方法的实现;

**有权无向图
**最小生成树: 建议使用优先级队列实现

无向带权图的实现

1. 图的顶点类

2. 带权图的边


3. 继承之前的优先级队列PriorityArrayQueue,略作调整:

4. 无向带权图的实现类

5. 测试无向带权图 及最小生成树

**有权有向图
**A. 最短路径问题SPP:
- 与有权无向图的最小生成树有些类似,但是并不一样:

a. 最小生成树是最少的边连接所有顶点,若加权,则应使权值和最小;

b. 最短路径则是一个点到分别其他各个顶点的加权值的最小值

- 这里的最短不是距离上的最短,是加权的最短,映射到实际问题,如花费最少,时间最短等;
- 解决该问题的算法:Dijkstra算法,不仅能找到任意连点间的最短路径,还可以找到某个指定点到其他所有顶点的最短路径;
**有权有向图的实现
**1. 图的定点类

2. 有权有向图最短路径问题的一个辅助类;

由于记住路径(权值的和)和父节点(即 distance & parentVertex,故而命名为DistPar);

3. 有权有向图的实现类

4. 测试有向带权图 及 最短路径

B. 每一对顶点之间的最短路径问题:Floyd算法;

1. Floyd算法的实现

2. 测试Floyd算法

我是今阳,如果想要进阶和了解更多的干货,欢迎关注公众号”今阳说“接收我的最新文章