ͼ

图形结构是一种比树形结构更复杂的非线性结构。在树形结构中,结点间具有分支层次关系,每一层上的结点只能和上一层中的至多一个结点相关,但可能和下一层的多个结点相关。而在图形结构中,任意两个结点之间都可能相关,即结点之间的邻接关系可以是任意的。

因此,图形结构被用于描述各种复杂的数据对象,在自然科学、社会科学和人文科学等许多领域有着非常广泛的应用 。图形结构在计算机科学、人工智能、电子线路分析、最短路径寻找、工程计划、化学化合物分析统计力学、遗传学、控制论语言学和社会科学等方面均有不同程度的应用可以这样说,图形结构在所有数据结构中应用最为广泛。如在地铁站中的线路图:

图的定义

图是一种数据结构,其中节点可以具有零个或多个相邻元素,两个节点的连接称之为边,节点在图形结构中也被称为顶点,一个顶点到另一个顶点的经过的的线路称为路径。

图形结构有3种类型:无向图、有向图、带权图 无向图:顶点A与顶点B之间的边是无方向的,可以从A到B,也可以从B到A 有向图:顶点A与顶点B之间的边是有方向的,可以从A到B,但不可以从B到A 带权图:顶点A与顶点B之间的边是带有属性的,如A到B的 距离。 图的表达方式

图的表达方式有两种:邻接矩阵(使用二维数组)和邻接表(使用数组+链表)

邻接矩阵

邻接矩阵是表示图形中各顶点之间的关系,矩阵的行和列对应各顶点,坐标位置上的值对于它们之间的关系,1为连接, 0为没有连接。在程序中用二维数组来实现。

邻接表

邻接表只关系存在的边,不需要去为不存在的边分配空间,因此比邻接矩阵来说,避免了不必要的空间浪费。在程序中用数组+链表的形式实现,数组存储对应的顶点,链表存储该顶点连接的所有顶点。

图的搜索算法

图形结构基础属性和方法

以下的代码演示都是以邻接矩阵表达方式来实现的

//图形结构(邻接矩阵) class Graph {      //存储图中所有顶点     private List vertexes;     //图形结构的邻接矩阵     private int[][] matrix;     //各顶点访问情况,true为已访问,false为未访问     private boolean[] visited;      /**      * 根据传入的顶点信息生成矩阵      * @param s      */     public Graph(String s[]) {         vertexes = new ArrayList<>();         for (String vertex : s){             (vertex);         }         matrix = new int[][];     }      /**      * 将俩个顶点连接,即生成边      * @param index1 顶点在集合中的索引      * @param index2      */     public void connect(int index1, int index2){         if (index1 < 0 || index1 >  || index2 < 0 || index2 > ){             throw new RuntimeException("该顶点未存在");         }         //将新的邻接添加的邻接矩阵中         matrix[index1][index2] = 1;         matrix[index2][index1] = 1;     }      /**      * 展示邻接矩阵      */     public void showGraphMatrix(){         for (int arr[] : matrix){             ((arr));         }     }          /**      * 获取顶点在邻接矩阵对应行row中的第一个邻接顶点下标      * @param row      * @return 当有邻接顶点时返回邻接顶点下标,没有则返回-1      */     public int getFirstNeighbor(int row){         for(int i =0; i<; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     }      /**      * 获取顶点在邻接矩阵对于行row中col列的下一个邻接顶点      * @param row      * @param col      * @return 当有邻接顶点时返回邻接顶点下标,没有则返回-1      */     public int getNeighbor(int row, int col){         for (int i=col+1; i<; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     } }  深度优先搜索

深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。这样的访问策略是优先往纵向进行深入挖掘,而不是对一个顶点的所有邻接顶点进行横线访问。简单来说就是一条路走到死,不行再掉头。

思路:从当前顶点选一个与之连接而未访问过的顶点,将当前节点往该邻接顶点移动,如果邻接顶点没有未访问的,则回溯到上一个顶点位置,继续该步骤。直到所有顶点都访问过。

往邻接但未访问过的顶点移动

邻接顶点没有未访问的,进行回溯,直到遇到未访问的邻接顶点

当所有顶点都被访问过时,退出算法

下面是深度优先搜索的过程动画

代码演示

public void dsf(){     visited = new boolean[()];     //以在集合中下标为0的顶点,进行深度搜索     dsf(visited, 0); }  /**  * 深度优先搜索  * @param visited  * @param row  */ public void dsf(boolean[] visited, int row){     //输出当前顶点     ((row) + " -> ");     //将当前顶点设为已访问     visited[row] = true;     //获取当前顶点的邻接顶点下标     int index = getFirstNeighbor(row);     //如果当前顶点有邻接顶点则进行深度搜索     while (index != -1){         //当邻接顶点未访问时,则递归遍历         if (visited[index] != true){             dsf(visited, index);         }         //当邻接顶点已访问时,则寻找另一个邻接顶点         index = getNeighbor(row, index);     } }  宽度优先搜索

宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。

宽度优先搜索算法类似于一个分层搜索的过程,宽度优先搜索算法需要一个队列以保持访问过顶点的顺序,以便按这个顺序来访问这些顶点的邻接顶点。

思路:依次访问当前顶点的邻接顶点,并按访问顺序将这些邻接顶点存储在队列中,当当前顶点的所有邻接顶点都被访问后,从队列中弹出一个顶点,以该顶点为当前顶点继续该步骤,直到所有顶点都被访问过。

依次访问当前顶点的所有邻接顶点,并把这些邻接顶点按访问顺序存储在队列中

当前顶点没有未访问的邻接顶点,从队列中弹出一个顶点,以该弹出顶点继续访问未访问的邻接顶点

注意,虽然图中的顶点都已经访问过了,但还是要等队列中的所有顶点弹出访问后,算法才结束

下面时宽度优先搜索的过程动画

代码演示

public void bfs(){     visited = new boolean[()];     以在集合中下标为0的顶点,进行广度优先搜索     bfs(visited, 0); }  /**  * 广度优先搜索  * @param visited  * @param row  */ public void bfs(boolean[] visited, int row){     //创建队列,存储遍历邻接顶点的顺序     LinkedList queue = new LinkedList();     //输出当前顶点     ((row) + " -> ");     //将当前顶点设为已访问     visited[row] = true;     //将当前顶点加入队列中     (row);     //当队列不为空时,即有未搜索的邻接顶点,进行搜索     while (!()){         //按顺序从队列中弹出邻接顶点下标         int last = (Integer)();         //获取该弹出顶点的邻接顶点下标         int index = getFirstNeighbor(last);         //当弹出顶点有邻接顶点时,进行广度搜索         while(index != -1){             //当邻接顶点未访问时             if(visited[index] != true){                 //输出该邻接顶点                 ((index) + " -> ");                 //把该邻接顶点设为已访问                 visited[index] = true;                 //将该邻接顶点加入队列                 Last(index);             }             //继续寻找弹出顶点的另一个邻接顶点             index = getNeighbor(last, index);         }     } }

完整演示代码

public class GraphDemo {     public static void main(String[] args) {         String[] s = {"A","B","C","D","E","F","G"};         Graph graph = new Graph(s);         //A-B A-C A-G A-F F-D F-E D-E E-G         (0, 1);         (0, 2);         (0, 6);         (0, 5);         (5, 3);         (5, 4);         (3, 4);         (4, 6);         ();          ();//A -> B -> C -> F -> D -> E -> G ->          ();         ();//A -> B -> C -> F -> G -> D -> E ->      } }  //图形结构 class Graph {     //存储图中所有顶点     private List vertexes;     //图形结构的邻接矩阵     private int[][] matrix;     //各顶点访问情况,true为已访问,false为未访问     private boolean[] visited;      /**      * 根据传入的顶点信息生成矩阵      * @param s      */     public Graph(String s[]) {         vertexes = new ArrayList<>();         for (String vertex : s){             (vertex);         }         matrix = new int[][];     }      /**      * 将俩个顶点连接,即生成边      * @param index1 顶点在集合中的索引      * @param index2      */     public void connect(int index1, int index2){         if (index1 < 0 || index1 >  || index2 < 0 || index2 > ){             throw new RuntimeException("该顶点未存在");         }         //将新的邻接添加的邻接矩阵中         matrix[index1][index2] = 1;         matrix[index2][index1] = 1;     }      /**      * 展示邻接矩阵      */     public void showGraphMatrix(){         for (int arr[] : matrix){             ((arr));         }     }      public void dsf(){         visited = new boolean[()];         //以在集合中下标为0的顶点,进行深度优先搜索         dsf(visited, 0);     }      /**      * 深度优先搜索      * @param visited      * @param row      */     public void dsf(boolean[] visited, int row){         //输出当前顶点         ((row) + " -> ");         //将当前顶点设为已访问         visited[row] = true;         //获取当前顶点的邻接顶点下标         int index = getFirstNeighbor(row);         //如果当前顶点有邻接顶点则进行深度搜索         while (index != -1){             //当邻接顶点未访问时,则递归遍历             if (visited[index] != true){                 dsf(visited, index);             }             //当邻接顶点已访问时,则寻找另一个邻接顶点             index = getNeighbor(row, index);         }     }      public void bfs(){         visited = new boolean[()];         以在集合中下标为0的顶点,进行广度优先搜索         bfs(visited, 0);     }      /**      * 广度优先搜索      * @param visited      * @param row      */     public void bfs(boolean[] visited, int row){         //创建队列,存储遍历邻接顶点的顺序         Queue queue = new ArrayDeque();         //输出当前顶点         ((row) + " -> ");         //将当前顶点设为已访问         visited[row] = true;         //将当前顶点加入队列中         (row);         //当队列不为空时,即有未搜索的邻接顶点,进行搜索         while (!()){             //按顺序从队列中弹出邻接顶点下标             int last = (Integer)();             //获取该弹出顶点的邻接顶点下标             int index = getFirstNeighbor(last);             //当弹出顶点有邻接顶点时,进行广度搜索             while(index != -1){                 //当邻接顶点未访问时                 if(visited[index] != true){                     //输出该邻接顶点                     ((index) + " -> ");                     //把该邻接顶点设为已访问                     visited[index] = true;                     //将该邻接顶点加入队列                     (index);                 }                 //继续寻找弹出顶点的另一个邻接顶点                 index = getNeighbor(last, index);             }         }     }      /**      * 获取顶点在邻接矩阵对应行row中的第一个邻接顶点下标      * @param row      * @return 当有邻接顶点时返回邻接顶点下标,没有则返回-1      */     public int getFirstNeighbor(int row){         for(int i =0; i<; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     }      /**      * 获取顶点在邻接矩阵对于行row中col列的下一个邻接顶点      * @param row      * @param col      * @return 当有邻接顶点时返回邻接顶点下标,没有则返回-1      */     public int getNeighbor(int row, int col){         for (int i=col+1; i<; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     } }

prim算法_数据结构与算法:图形结构相关推荐

  1. prim算法_数据结构与算法

    根据MOOC上课程总结,文章目录为: 一.引论 数据结构的基本概念 数据的逻辑结构和存储结构 算法及其时间复杂度 时间复杂度及应用 二.线性表 线性表的概念及顺序存储 单链表的概念及其基本操作 建立单 ...

  2. 循环首次适应算法_数据结构与算法之2——排序问题

    排序真的是数据结构与算法中的重中之重啊,无论是对编程能力的提升,以后工作后的应用,或者是应对面试的时候都是经常需要用到的.基本的几个经典排序一定要做到滚瓜烂熟,能够做到给你一个具体的排序算法题,一定能 ...

  3. 尚硅谷01 数据结构与算法_数据结构与算法介绍+稀疏数组

    数据结构与算法的关系 几个实际编程中遇到的问题 要想写出优秀的算法,首先应该能读懂别人写好的算法. 将生活中遇到的实际问题,使用程序来解决 线性结构和非线性结构 线性结构和非线性结构的关系: 数据结构 ...

  4. python数据结构算法_数据结构与算法(Python)

    数据结构与算法(Python) Why? 我们举一个可能不太恰当的例子: 如果将最终写好运行的程序比作战场,我们码农便是指挥作战的将军,而我们所写的代码便是士兵和武器. 那么数据结构和算法是什么?答曰 ...

  5. dijkstra 算法_数据结构与算法—单源最短路径dijkstra算法

    介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...

  6. mooc数据结构与算法python版期末测验_中国大学MOOC(慕课)_数据结构与算法Python版_测试题及答案...

    中国大学MOOC(慕课)_数据结构与算法Python版_测试题及答案 更多相关问题 采用fopen()函数打开文件,支持文件读取的参数有: [简答题]简单阐述高分子材料热-机械特征及成型加工的关系,并 ...

  7. 嵌入式团队培训_数据结构和算法概述

    嵌入式团队培训_数据结构与算法概述 要求:理解并记忆即可,会求解算法的时间复杂度 一:数据结构 1.逻辑结构: 2.物理结构 3.抽象数据类型 二:算法 1.算法的五个基本特征: 2.算法设计的要求 ...

  8. 获取用户列表为空_数据结构和算法(Golang实现)(15)常见数据结构-列表

    列表 一.列表 List 我们又经常听到 列表 List 数据结构,其实这只是更宏观的统称,表示存放数据的队列. 列表 List:存放数据,数据按顺序排列,可以依次入队和出队,有序号关系,可以取出某序 ...

  9. vrp 节约算法 c++_数据结构和算法(Golang实现)(8.1)基础知识-前言

    基础知识 学习数据结构和算法.我们要知道一些基础的知识. 一.什么是算法 算法(英文algorithm)这个词在中文里面博大精深,表示算账的方法,也可以表示运筹帷幄的计谋等.在计算机科技里,它表示什么 ...

最新文章

  1. web应用的绝对路径和相对路径
  2. c语言函数调用参数太少,调用input_message的参数太少在主函数中 是神马意思 大神们帮帮我...
  3. 利用docker编译Android源码
  4. php+gd库的源码安装
  5. SAP Fiori Elements List Report Smart Table Toolbar 的 XML 视图实现
  6. 二分答案——yyy2015c01 的 U 盘(洛谷 P2370)
  7. hlsl之ambient
  8. JQuery:视频+实战总结
  9. oracle大黑点,R语言实现交通行业事故案例之黑点确定 - 数据分析
  10. 如何在C#窗体中定义全局变量
  11. 久其报表节点汇总_久其通用数据管理平台常见公式
  12. spring 通过yml格式配置log日志
  13. 计算机房等电位接地规范,电子计算机机房接地装置设计要求
  14. [存储] Cobar使用文档(可用作MySQL大型集群解决方案)
  15. 浅层介质过滤器工作原理介绍
  16. 新塘单片机烧写器_新唐单片机烧录工具-Nuvoton ICP Programming Tool下载v3.00.6909官方免费版-ucbug下载站...
  17. 样本均值的特征与分布
  18. 短信验证码,在键盘显示验证码
  19. 发散阅读、拓宽思路【PageRank、Tf-Idf、协同过滤、分布式训练、StyleTransfer、Node2vec】
  20. Java——entity(实体类)的写法规范

热门文章

  1. ipad如何与计算机连接网络连接不上,平板电脑可以连接无线网络但上不了网如何解决...
  2. C语言程序设计教程(第三版)课后习题6.1
  3. 抽象数据类型三元组Triplet基本操作与实现 严蔚敏版
  4. 积水成渊:用github gist收藏你的代码片段
  5. 计算机屏幕尺寸不是全屏,电脑屏幕有黑边撑不满怎么办_电脑屏幕不能全屏显示的解决方法...
  6. Android开发工具类
  7. 苹果怎么换行打字_2周内将你的打字速度提高3倍的方法
  8. 第五十八章 SQL函数 FLOOR
  9. 山西大同大学计算机分数线,山西大同大学录取分数线2021是多少分(附历年录取分数线)...
  10. flappybird原理解析 JQuery版本