电商| 物流| 科技| 创业| 经商| 运营| 科普| 财经| 文娱| AI| 物联| 品牌| 会议| 政策| 时尚| 健康| 家居| 金融| 农业| 汽车| 房产| 百科| 生活| 游戏| 管理| 快讯
 
首页 » 资讯 » 科技 » 数据结构与算法:图形结构

数据结构与算法:图形结构

放大字体  缩小字体 时间:2020-10-22 12:04    热度:263
ͼ图形结构是一种比树形结构更复杂的非线性结构。在树形结构中,结点间具有分支层次关系,每一层上的结点只能和上一层中的至多一。。。

ͼ

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

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

图的定义

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

图形结构有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;           public Graph(String s[]) {         vertexes = new ArrayList<>();         for (String vertex : s){             vertexes.add(vertex);         }         matrix = new int[s.length][s.length];     }           public void connect(int index1, int index2){         if (index1 < 0 || index1 > matrix.length || index2 < 0 || index2 > matrix.length){             throw new RuntimeException("该顶点未存在");         }         //将新的邻接添加的邻接矩阵中         matrix[index1][index2] = 1;         matrix[index2][index1] = 1;     }           public void showGraphMatrix(){         for (int arr[] : matrix){             System.out.println(Arrays.toString(arr));         }     }               public int getFirstNeighbor(int row){         for(int i =0; i<matrix.length; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     }           public int getNeighbor(int row, int col){         for (int i=col+1; i<matrix.length; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     } }  深度优先搜索

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

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

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

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

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

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

代码演示

public void dsf(){     visited = new boolean[vertexes.size()];     //以在集合中下标为0的顶点,进行深度搜索     dsf(visited, 0); }   public void dsf(boolean[] visited, int row){     //输出当前顶点     System.out.print(vertexes.get(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[vertexes.size()];     ////以在集合中下标为0的顶点,进行广度优先搜索     bfs(visited, 0); }   public void bfs(boolean[] visited, int row){     //创建队列,存储遍历邻接顶点的顺序     linkedList queue = new linkedList();     //输出当前顶点     System.out.print(vertexes.get(row) + " -> ");     //将当前顶点设为已访问     visited[row] = true;     //将当前顶点加入队列中     queue.add(row);     //当队列不为空时,即有未搜索的邻接顶点,进行搜索     while (!queue.isEmpty()){         //按顺序从队列中弹出邻接顶点下标         int last = (Integer)queue.removeFirst();         //获取该弹出顶点的邻接顶点下标         int index = getFirstNeighbor(last);         //当弹出顶点有邻接顶点时,进行广度搜索         while(index != -1){             //当邻接顶点未访问时             if(visited[index] != true){                 //输出该邻接顶点                 System.out.print(vertexes.get(index) + " -> ");                 //把该邻接顶点设为已访问                 visited[index] = true;                 //将该邻接顶点加入队列                 queue.addLast(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         graph.connect(0, 1);         graph.connect(0, 2);         graph.connect(0, 6);         graph.connect(0, 5);         graph.connect(5, 3);         graph.connect(5, 4);         graph.connect(3, 4);         graph.connect(4, 6);         graph.showGraphMatrix();          graph.dsf();//A -> B -> C -> F -> D -> E -> G ->          System.out.println();         graph.bfs();//A -> B -> C -> F -> G -> D -> E ->      } }  //图形结构 class Graph {     //存储图中所有顶点     private List vertexes;     //图形结构的邻接矩阵     private int[][] matrix;     //各顶点访问情况,true为已访问,false为未访问     private boolean[] visited;           public Graph(String s[]) {         vertexes = new ArrayList<>();         for (String vertex : s){             vertexes.add(vertex);         }         matrix = new int[s.length][s.length];     }           public void connect(int index1, int index2){         if (index1 < 0 || index1 > matrix.length || index2 < 0 || index2 > matrix.length){             throw new RuntimeException("该顶点未存在");         }         //将新的邻接添加的邻接矩阵中         matrix[index1][index2] = 1;         matrix[index2][index1] = 1;     }           public void showGraphMatrix(){         for (int arr[] : matrix){             System.out.println(Arrays.toString(arr));         }     }      public void dsf(){         visited = new boolean[vertexes.size()];         //以在集合中下标为0的顶点,进行深度优先搜索         dsf(visited, 0);     }           public void dsf(boolean[] visited, int row){         //输出当前顶点         System.out.print(vertexes.get(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[vertexes.size()];         ////以在集合中下标为0的顶点,进行广度优先搜索         bfs(visited, 0);     }           public void bfs(boolean[] visited, int row){         //创建队列,存储遍历邻接顶点的顺序         Queue queue = new ArrayDeque();         //输出当前顶点         System.out.print(vertexes.get(row) + " -> ");         //将当前顶点设为已访问         visited[row] = true;         //将当前顶点加入队列中         queue.add(row);         //当队列不为空时,即有未搜索的邻接顶点,进行搜索         while (!queue.isEmpty()){             //按顺序从队列中弹出邻接顶点下标             int last = (Integer)queue.poll();             //获取该弹出顶点的邻接顶点下标             int index = getFirstNeighbor(last);             //当弹出顶点有邻接顶点时,进行广度搜索             while(index != -1){                 //当邻接顶点未访问时                 if(visited[index] != true){                     //输出该邻接顶点                     System.out.print(vertexes.get(index) + " -> ");                     //把该邻接顶点设为已访问                     visited[index] = true;                     //将该邻接顶点加入队列                     queue.add(index);                 }                 //继续寻找弹出顶点的另一个邻接顶点                 index = getNeighbor(last, index);             }         }     }           public int getFirstNeighbor(int row){         for(int i =0; i<matrix.length; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     }           public int getNeighbor(int row, int col){         for (int i=col+1; i<matrix.length; i++){             if (matrix[row][i] != 0){                 return i;             }         }         return -1;     } }   

关于数据结构与算法:图形结构的要点介绍,希望对大家了解数据结构与算法:图形结构有所帮助,如有侵权,联系我们37442552@qq.com。
 
你可能感兴趣:
 
芬兰政府指责微软对诺基亚始乱终弃 承诺一个都

2016-05-28

本周早些时候,微软宣称它将会裁减1850个工作岗位,其中有1350个工作位于芬兰。人们认为微软裁员之举预示着该公司新手机开发工作的终结。据外电报道,芬兰政…

三星最新发布的C5酷似iPhone 6 售价只有后者一半
三星最新发布的C5酷似iPhone 6 售价只有后者一

2016-05-28 三星 C5

三星最新发布的C5酷似iPhone 6 售价只有后者一半;三星周四在中国市场发布的最新款智能手机C5酷似苹果iPhone 6和6S。

苹果下架腾讯全系产品只是虚惊一场 淘宝、京东

2016-05-29 苹果 腾讯 APP

苹果下架腾讯全系产品只是虚惊一场 淘宝、京东等APP也未能幸免;苹果下架腾讯全系产品,搜索出现大面积瘫痪,淘宝、京东等APP也未能幸免。据了解,腾讯也曾因…

华为为何要在此时向三星发起专利战?背后的原因究竟是什么?
华为为何要在此时向三星发起专利战?背后的原因

2016-05-29 华为 三星 专利

华为为何要在此时向三星发起专利战?背后的原因究竟是什么?作为中国企业的华为,其在专利,尤其是与通信相关的专利的申请和积累在全球均名列前茅。而华为之…

2016中国互联网大会时间地点主题 互联网大会有何亮点?
2016中国互联网大会时间地点主题 互联网大会有

2016-06-02 2016 中国 互联网 大会

 由中国互联网协会主办的2016(第十五届)中国互联网大会将于6月21-23日在北京国际会议中心举行。本届大会主题为“繁荣网络经济 建设网络强国”。

Facebook周四下架了突发新闻通知应用Notify
Facebook周四下架了突发新闻通知应用Notify

2016-06-04 Facebook Notify

Facebook周四下架了突发新闻通知应用Notify;Facebook发言人在发给科技博客The Verge的声明中表示,Notify采用的技术将集成到Messenger中,所以内容发布商可…

阿里回应被SEC问询 马云:那并不代表公司有问题

2016-06-04

近期,阿里巴巴接受美国证券交易委员会问询,16年来日本软银集团首度出售手中阿里股份,阿里股价震荡,相关消息持续引发关注。2

iphone7上市时间确定 国行或5288元起售

2016-06-04

根据国外网站PC-Tablet的报导称,苹果仍将下一代iPhone的发布时刻定在今年9月份,至于详细日期则为美国当地时刻9月9日或9月16日

印度最大手机厂商明年来华抢市场 有戏吗?

2016-06-04

Micromax联合创始人维卡斯贾因(VikasJain)当天在香港举办的一场科技大会上表明,公司的目标是在2020年前变成按销量核算的全球第

索尼Xperia X系列终于要来了6月8日携手周杰伦发

2016-06-04

索尼的手机一直以来都是以拍照以及颜值闻名的,在今年的MWC2016大会上,索尼曾经发布了一款Xperia X系列产品中的Xperia XPerform

 
热点图文
三星最新发布的C5酷似iPhone 6 售价只有后者一半

三星最新发布的C5酷似iPhone 6 售价只有后者一半

华为为何要在此时向三星发起专利战?背后的原因究竟是什么?

华为为何要在此时向三星发起专利战?背后的原因究竟是什么?

2016中国互联网大会时间地点主题 互联网大会有何亮点?

2016中国互联网大会时间地点主题 互联网大会有何亮点?

Facebook周四下架了突发新闻通知应用Notify

Facebook周四下架了突发新闻通知应用Notify

戴尔确认出售软件业务:4年净赔16亿美元

戴尔确认出售软件业务:4年净赔16亿美元

沉迷于成人VR的日本年轻人  年轻男女都拒绝恋爱(图)

沉迷于成人VR的日本年轻人 年轻男女都拒绝恋爱(图)

今日头条母公司字节跳动科创板上市成功几率多大?

今日头条母公司字节跳动科创板上市成功几率多大?

余承东回应:华为开发自有系统 以防美国科技巨头不授权现有系统

余承东回应:华为开发自有系统 以防美国科技巨头不授权现有系统

 
经商宝 — 经商创业营销推广电子商务门户 网站地图 | 关于我们 | 特惠服务 | 人才招聘 | 联系我们 | 法律声明