大纲

图的表示
图的遍历

  • 深度优先(连通性,路径,二分图检测,环的检测,floodfill)
  • 广度优先(无权图的最短路径)

欧拉路径
哈密尔顿路径
状态压缩
image.png

论有什么用?

培养思维,可以遇到新的问题的时候可以借助前人的方式,去创新性的解决新的问题。


图Graph

是由顶点的有穷非空集合和顶点之间的边的集合组成。表示方法为G(V,E)

  • 线性表中的数据元素称为元素,树中的数据元素称为结点,图中的数据元素称为顶点
  • 图的结构中不允许没有顶点

概念

图的定义

分类

  • 有向图
  • 无向图

image.png

G(V,E) 表示为V={A,B,C,D} E={(A,B),(B,C), (C,D), (D,A), (A,C)}

  1. 图结构中,不允许没有顶点
  2. 图中,数据元素称为顶点
  3. 图结构中,两个顶点之间的关系用边来表示

有向图 从顶点V1到V2的边有方向,则称为这条边为有向边,也称为弧。由顶点和弧构成。弧有弧尾和弧头之分

表示方式

<V1, V2> => <弧尾, 弧头>

无向图 如果任意两点之间都存在边,则称该图为无向完全图。 由顶点和边构成

表示方式

(V1,V2)

  • 含有n个顶点的无向图有n(n-1)/2条边

子图 Subgraph

image.png
图的顶点与边的关系

image.png
路径长度

树中根结点到任意结点的路径是唯一的。但是图中顶点与顶点之间的路径不是唯一的

路径长度是路径上的边或弧的数目

第一个顶点到最后一个顶点相同的路径称为回路或环。

边|弧附带的数值。可以表示为一个顶点到另一个顶点的距离。

路径

从顶点i出发经过一系列的边能够到达j的路径

连通,连通图,连通分量

图中顶点存在路径,两个顶点存在路径说明是连通

若任意两顶点都是连通的,则称为连通图。

图的存储

图的存储结构

图的机构比较复杂,任意两个顶点之间都可能会存在关系。

临接矩阵

用两个数组来表示图。一个一维数组存储顶点信息,一个二维数组存储图中边或弧的信息。

空间复杂度0(n^2)

image.png
image.png
代码
image.png

  1. // 请输入两个数, 一个表示V 一个E。V表示有多少个节点,E表示有多少边。
  2. /*
  3. 以上面的例子
  4. 5 6
  5. 0 1
  6. 0 2
  7. 1 3
  8. 1 4
  9. 2 3
  10. 3 4
  11. */
  12. import java.io.File;
  13. import java.util.Arrays;
  14. import java.util.Scanner;
  15. public class AdjMatrix {
  16. private int V; //节点
  17. private int E; //边
  18. private int[][] adj; //临街矩阵
  19. public AdjMatrix(String fileName){
  20. File file = new File(fileName); // 从文件读入
  21. try(Scanner scanner = new Scanner(file)){
  22. V = scanner.nextInt();
  23. E = scanner.nextInt();
  24. System.out.println("结点:"+V+"\t"+"边数:"+E);
  25. adj = new int[V][V];
  26. for(int i=0; i<E; i++){// 遍历
  27. int a= scanner.nextInt();
  28. int b = scanner.nextInt();
  29. adj[a][b] = 1;
  30. adj[b][a] = 1;
  31. }
  32. }catch (Exception e){
  33. e.printStackTrace();
  34. }
  35. }
  36. @Override
  37. public String toString() {
  38. for(int i=0; i<V; i++){
  39. System.out.println(Arrays.toString(adj[i]));
  40. }
  41. return "";
  42. }
  43. public static void main(String[] args) {
  44. AdjMatrix adjMatrix = new AdjMatrix("data.txt");
  45. System.out.println(adjMatrix);
  46. }
  47. }
  48. 结点:5 边数:6
  49. [0, 1, 1, 0, 0]
  50. [1, 0, 0, 1, 1]
  51. [1, 0, 0, 1, 0]
  52. [0, 1, 1, 0, 1]
  53. [0, 1, 0, 1, 0]

临接链表

数组与链表相结合,孩子表示法,将顶点集合存入数组,并对结点的孩子链式存储。
image.png
image.png

代码

  1. import java.io.File;
  2. import java.io.FileNotFoundException;
  3. import java.util.Arrays;
  4. import java.util.LinkedList;
  5. import java.util.Scanner;
  6. public class AdjList {
  7. private int V;
  8. private int E;
  9. private LinkedList<Integer>[] adj;
  10. public AdjList(String fileName){
  11. File file = new File(fileName);
  12. try(Scanner scanner = new Scanner(file)){
  13. V =scanner.nextInt(); // 读取结点
  14. E = scanner.nextInt();// 读取边
  15. // 初始化
  16. adj = new LinkedList[V];
  17. for(int i=0; i<V; i++){
  18. adj[i] = new LinkedList<Integer>();
  19. }
  20. for(int i=0; i<E; i++){
  21. int a = scanner.nextInt();
  22. int b = scanner.nextInt();
  23. adj[a].add(b);
  24. adj[b].add(a);
  25. }
  26. } catch (FileNotFoundException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. @Override
  31. public String toString() {
  32. for(int i=0; i<V;i++){
  33. System.out.println(adj[i]);
  34. }
  35. return "";
  36. }
  37. public static void main(String[] args) {
  38. AdjList adjList = new AdjList("data.txt");
  39. System.out.println(adjList);
  40. }
  41. }
  42. [1, 2]
  43. [0, 3, 4]
  44. [0, 3]
  45. [1, 2, 4]
  46. [1, 3]

十字链表

十字链表将临接表与逆临接表结合

定义结构
image.png

顶点结构

  • firstin 表示入边表头指针,指向该顶点的入边表中的第一个结点。
  • firstout 表示出边表头指针,指向该顶点的出边表中的第一个结点。

边结构

  • tailvex是弧起点在顶点表的下标
  • headvex是指弧终点在顶点表的下标
  • headlink指入边标指针域
  • taillink指边表的指针与,指向起点相同的下一条边

图的遍历

从图的某一个顶点触发访图中其余顶点,且使每一个顶点仅被访问一次。

  • 深度优先遍历Depth_First_Search
  • 广度优先遍历Breadth_First_Search

DFS

image.png

BFS

image.png

最小生成树

Prim