通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边

2023-12-06 07:08

本文主要是介绍通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

**通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边(Java实现)

**

package graph;import java.io.IOException;
import java.util.Scanner;public class ListCycle 
{private class ENode {int ivex;       // 该边所指向的顶点的位置ENode nextEdge; // 指向下一条弧的指针}// 邻接表中表的顶点private class VNode {int color;//顶点颜色;int d;//初始时间戳;int f;//结束时间戳;char data;          // 顶点信息ENode firstEdge;    // 指向第一条依附该顶点的弧VNode pre;};int time;private VNode[] mVexs;  // 顶点数组/* * 创建图(自己输入数据)*/public ListCycle() {// 输入"顶点数"和"边数"System.out.printf("input vertex number: ");int vlen = readInt();System.out.printf("input edge number: ");int elen = readInt();if ( vlen < 1 || elen < 1 || (elen > (vlen*(vlen - 1)))) {System.out.printf("input error: invalid parameters!\n");return ;}// 初始化"顶点"mVexs = new VNode[vlen];for (int i = 0; i < mVexs.length; i++) {System.out.printf("vertex(%d): ", i);mVexs[i] = new VNode();mVexs[i].data = readChar();mVexs[i].firstEdge = null;}// 初始化"边"//mMatrix = new int[vlen][vlen];for (int i = 0; i < elen; i++) {// 读取边的起始顶点和结束顶点System.out.printf("edge(%d):", i);char c1 = readChar();char c2 = readChar();int p1 = getPosition(c1);int p2 = getPosition(c2);// 初始化node1ENode node1 = new ENode();node1.ivex = p2;// 将node1链接到"p1所在链表的末尾"if(mVexs[p1].firstEdge == null)mVexs[p1].firstEdge = node1;elselinkLast(mVexs[p1].firstEdge, node1);}}/** 创建图(用已提供的矩阵)** 参数说明:*     vexs  -- 顶点数组*     edges -- 边数组*/public ListCycle(char[] vexs, char[][] edges) {// 初始化"顶点数"和"边数"int vlen = vexs.length;int elen = edges.length;// 初始化"顶点"mVexs = new VNode[vlen];for (int i = 0; i < mVexs.length; i++) {mVexs[i] = new VNode();mVexs[i].data = vexs[i];mVexs[i].firstEdge = null;}// 初始化"边"for (int i = 0; i < elen; i++) {// 读取边的起始顶点和结束顶点char c1 = edges[i][0];char c2 = edges[i][1];// 读取边的起始顶点和结束顶点int p1 = getPosition(edges[i][0]);int p2 = getPosition(edges[i][1]);// 初始化node1ENode node1 = new ENode();node1.ivex = p2;// 将node1链接到"p1所在链表的末尾"if(mVexs[p1].firstEdge == null)mVexs[p1].firstEdge = node1;elselinkLast(mVexs[p1].firstEdge, node1);}}/** 将node节点链接到list的最后*/private void linkLast(ENode list, ENode node) {ENode p = list;while(p.nextEdge!=null)p = p.nextEdge;p.nextEdge = node;}/** 返回ch位置*/private int getPosition(char ch) {for(int i=0; i<mVexs.length; i++)if(mVexs[i].data==ch)return i;return -1;}/** 读取一个输入字符*/private char readChar() {char ch='0';do {try {ch = (char)System.in.read();} catch (IOException e) {e.printStackTrace();}} while(!((ch>='a'&&ch<='z') || (ch>='A'&&ch<='Z')));return ch;}/** 读取一个输入字符*/private int readInt() {Scanner scanner = new Scanner(System.in);return scanner.nextInt();}/** 深度优先搜索遍历图的递归实现*/private void DFS_visit(int i, boolean[] visited) {ENode node;//time= time+1;mVexs[i].d = ++time;mVexs[i].color=0;//1表示该节点颜色为灰色visited[i] = true;//System.out.printf("%c(%d) ", mVexs[i].data,mVexs[i].d);//颜色node = mVexs[i].firstEdge;while (node != null) {if (mVexs[node.ivex].color == -1) {System.out.println("("+i+","+node.ivex+")---树边");DFS_visit(node.ivex, visited);  }else if(mVexs[node.ivex].color == 0){System.out.println("("+i+","+node.ivex+")---后向边");}else{if(mVexs[i].color < mVexs[node.ivex].d)System.out.println("("+i+","+node.ivex+")---前向边");else if(mVexs[i].color > mVexs[node.ivex].d)System.out.println("("+i+","+node.ivex+")---横跨边");}     node = node.nextEdge;}mVexs[i].color=1;//time=time+1;mVexs[i].f = ++time;//System.out.printf("%c(%d) ", mVexs[i].data,mVexs[i].f);}/** 深度优先搜索遍历图*/public void DFS() {time = 0;boolean[] visited = new boolean[mVexs.length];       // 顶点访问标记// 初始化所有顶点都没有被访问for ( int i = 0; i <mVexs.length; i++){mVexs[i].color = -1;//初始化所有顶点都为白色mVexs[i].pre=null;visited[i] = false;}// System.out.printf("DFS: ");for (int j= 0; j < mVexs.length; j++) {if (!visited[j])DFS_visit(j, visited);}System.out.printf("\n");}/** 打印矩阵队列图*/public void print() {System.out.printf("List Graph:\n");for (int i = 0; i < mVexs.length; i++) {System.out.printf("%d(%c): ", i, mVexs[i].data);ENode node = mVexs[i].firstEdge;while (node != null) {System.out.printf("%d(%c) ", node.ivex, mVexs[node.ivex].data);node = node.nextEdge;}System.out.printf("\n");}}public static void main(String[] args) {char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};char[][] edges = new char[][]{{'A', 'B'}, {'B', 'C'}, {'B', 'E'}, {'B', 'F'}, {'C', 'E'}, {'D', 'C'}, {'E', 'B'}, {'E', 'D'}, {'F', 'G'}}; ListCycle pG;// 自定义"图"(输入矩阵队列)//pG = new ListDG();// 采用已有的"图"pG = new ListCycle(vexs, edges);pG.print();   // 打印图pG.DFS();     // 深度优先遍}}

这篇关于通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/460891

相关文章

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实

MyBatis分页插件PageHelper深度解析与实践指南

《MyBatis分页插件PageHelper深度解析与实践指南》在数据库操作中,分页查询是最常见的需求之一,传统的分页方式通常有两种内存分页和SQL分页,MyBatis作为优秀的ORM框架,本身并未提... 目录1. 为什么需要分页插件?2. PageHelper简介3. PageHelper集成与配置3.

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.