本文主要是介绍通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
**通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边(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(); // 深度优先遍}}
这篇关于通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!