• 图Graph的存储、图的广度优先搜索和深度优先搜索(待更新)


    目录

    一、图的两种存储方式

    1.邻接矩阵

    2.邻接表


    生活中处处有图Graph的影子,例如交通图,地图,电路图等,形象的表示点与点之间的联系。

    首先简单介绍一下图的概念和类型:

     

    图的的定义:图是由一组顶点和一组能够将两个顶点相连的边组成的

    图的类型:

    顶点之间的连接方向:无方向-->无向图  有方向-->有向图 

    边上是否有权值:有-->带权图  无-->无权图

    以下分别是:无向无权、有向无权、无向有权、有向有权图

     

     

    一、图的两种存储方式

    1.邻接矩阵

    存储原理:邻接矩阵是一种用数组来表示图的方法,其中矩阵的行和列表示图中的顶点,矩阵元素表示顶点之间是否有边相连。具体来说,如果顶点v和顶点u之间有边,则矩阵的第u行第v列的元素为1;否则为0。带权值则为权值,没有相连的为0。

    优点:

    • 结构简单,易于理解和实现。

    • 对于稠密图,邻接矩阵的空间利用率较高。

    • 可以方便地计算出图中节点的度(即与该节点相邻的节点的数量)。

    缺点:

    • 对于稀疏图,邻接矩阵可能占用大量空间。

    • 访问相邻节点的速度较慢,需要进行遍历操作。

    示例:下图的邻接矩阵存储

     

    代码实现 

    1. import java.util.Arrays;
    2. //邻接矩阵
    3. public class Graph01 {
    4. char[] val;//顶点数据
    5. int[][] edges;//二维数组记录边
    6. Vertex[] vertices;//顶点类数组
    7. int N;//表大小
    8. public Graph01(char[] arr) {
    9. this.N = arr.length;
    10. //初始化顶点数据
    11. this.val = Arrays.copyOf(arr, arr.length);
    12. this.edges = new int[this.N][this.N];
    13. this.vertices = new Vertex[this.N];
    14. for (int i = 0; i < this.N; i++) {
    15. this.vertices[i] = new Vertex(arr[i]);
    16. }
    17. }
    18. private class Vertex {
    19. Character val;
    20. public Vertex(Character val) {
    21. this.val = val;
    22. }
    23. }
    24. //打印邻接矩阵
    25. public void show() {
    26. System.out.format("%5c", 32);
    27. for (int i = 0; i < this.N; i++) {
    28. System.out.format("%5c", this.val[i]);
    29. }
    30. System.out.println();
    31. for (int i = 0; i < this.N; i++) {
    32. System.out.format("%5c", this.val[i]);
    33. for (int j = 0; j < this.N; j++) {
    34. System.out.format("%5d", this.edges[i][j]);
    35. }
    36. System.out.println();
    37. }
    38. }
    39. public static void main(String[] args) {
    40. char[] arr = {'A', 'E', 'F', 'G', 'H', 'P'};
    41. Graph01 graph01 = new Graph01(arr);
    42. // 构建边集
    43. int[][] edges = graph01.edges;
    44. edges[0][1] = 5;
    45. edges[0][2] = 4;
    46. edges[0][3] = 2;
    47. edges[1][0] = 5;
    48. edges[1][3] = 1;
    49. edges[1][4] = 3;
    50. edges[2][0] = 4;
    51. edges[3][0] = 2;
    52. edges[3][1] = 1;
    53. edges[3][4] = 2;
    54. edges[3][5] = 4;
    55. edges[4][1] = 3;
    56. edges[4][3] = 2;
    57. edges[4][5] = 3;
    58. edges[5][3] = 4;
    59. edges[5][4] = 3;
    60. // 调用打印方法
    61. graph01.show();
    62. }
    63. }

    打印结果 : 

     

    2.邻接表

    存储原理:

    邻接表中的每个节点都对应一个链表,链表中的每个元素都是一个顶点(或节点),表示与当前节点相邻的节点。这种方式在处理稀疏图(即边的数量远小于顶点的数量)时效率较高。

    优点:

    • 存储空间开销较小,适用于稀疏图。

    • 查找速度快,可以直接通过索引访问相邻节点。

    • 可动态添加、删除节点和边。

    缺点:

    • 存储结构相对复杂,不利于处理大规模数据。

    • 空间利用率不高,对于稠密图可能存在大量未使用的节点和边。

    代码实现 

    1. import java.util.ArrayList;
    2. import java.util.Arrays;
    3. import java.util.List;
    4. //邻接表
    5. public class Graph02 {
    6. char[] val;//顶点数据
    7. List[] edgesList;//边连接
    8. Vertex[] vertices;
    9. int N;//表大小
    10. public Graph02(char[] arr){
    11. this.N = arr.length;
    12. this.val = Arrays.copyOf(arr,arr.length);
    13. this.edgesList = new List[this.N];
    14. this.vertices = new Vertex[this.N];
    15. for (int i = 0; i < this.N; i++) {
    16. this.vertices[i] = new Vertex(arr[i]);
    17. this.edgesList[i] = new ArrayList<>();
    18. }
    19. }
    20. private class Vertex{
    21. Character val;
    22. public Vertex(Character val){
    23. this.val = val;
    24. }
    25. }
    26. public void show(){
    27. //打印邻接矩阵
    28. for (int i = 0; i <this.N; i++) {
    29. System.out.format("%-3c",this.val[i]);
    30. List list = this.edgesList[i];
    31. list.stream().forEach(item->{
    32. System.out.format("%d-->",item);
    33. });
    34. System.out.println();
    35. }
    36. }
    37. public static void main(String[] args) {
    38. char[] arr = {'A', 'E', 'F', 'G', 'H', 'P'};
    39. Graph02 graph02 = new Graph02(arr);
    40. // 构建边集
    41. List[] edges = graph02.edgesList;
    42. edges[0].add(1);
    43. edges[0].add(2);
    44. edges[0].add(3);
    45. edges[1].add(0);
    46. edges[1].add(3);
    47. edges[1].add(4);
    48. edges[2].add(0);
    49. edges[3].add(0);
    50. edges[3].add(1);
    51. edges[3].add(4);
    52. edges[3].add(5);
    53. edges[4].add(1);
    54. edges[4].add(3);
    55. edges[4].add(5);
    56. edges[5].add(3);
    57. edges[5].add(4);
    58. // 调用打印方法
    59. graph02.show();
    60. }
    61. }

    打印结果 :

  • 相关阅读:
    Webpack与Vite热更新差异对比
    前端不安装Nginx情况下部署
    问题记录--VSCode、CMake、MSVC编译,可执行文件无输出
    路由规划——运输距离的估算
    VMware Workstation 15 安装教程
    MS35657步进电机驱动器可兼容DRV8824
    【云驻共创】HCSD 大咖直播–就业指南
    【内存拷贝函数:memcpy与memmove】
    146.LRU缓存
    GPT语言模型
  • 原文地址:https://blog.csdn.net/weixin_63541561/article/details/134543672