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

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

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

揭秘世界上那些同时横跨两大洲的国家

我们在《世界人口过亿的一级行政区分布》盘点全球是那些人口过亿的一级行政区。 现在我们介绍五个横跨两州的国家,并整理七大洲和这些国家的KML矢量数据分析分享给大家,如果你需要这些数据,请在文末查看领取方式。 世界上横跨两大洲的国家 地球被分为七个大洲分别是亚洲、欧洲、北美洲、南美洲、非洲、大洋洲和南极洲。 七大洲示意图 其中,南极洲是无人居住的大陆,而其他六个大洲则孕育了众多国家和

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s