通过深度优先算法进行拓扑排序(Java)

package graph;
//拓扑排序用深度优先算法实现
import java.io.IOException;
import java.util.Scanner;
import java.util.Stack;
public class Topological
{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 Topological() {// 输入"顶点数"和"边数"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 Topological(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();}/* 深度优先搜索遍历图的递归实现*/Stack<Integer> stack = new Stack<Integer>();//辅助栈;public 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;stack.push(i);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.print("\n拓扑排序为:");for (int i = 0; i < mVexs.length; i++) {System.out.print(mVexs[stack.pop()].data+" ");}}/** 打印矩阵队列图*/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[][] { { 'B', 'A' }, { 'B', 'D' }, { 'A', 'G' }, { 'C', 'G' }, { 'D', 'F' },{ 'C', 'F' },{ 'D', 'E' },};Topological pG;// 自定义"图"(输入矩阵队列)// pG = new ListDG();// 采用已有的"图"pG = new Topological(vexs, edges);pG.print(); // 打印图pG.DFS(); // 深度优先遍}}

通过深度优先算法进行拓扑排序(算法导论)相关推荐

  1. 【zz】如何去理解 拓扑排序算法

    from http://www.cnblogs.com/shanyou/archive/2006/11/16/562861.html 查看Castle的代码,在Castle.Core中内部的数据结构采 ...

  2. vant coupon 时间戳如何计算_计软考研双日练 | 如何计算拓扑排序算法的时间复杂度?...

    ☝☝☝ 软件工程考研独家平台 撰稿 | 康康哥 编辑 | 丽丽姐 本文由懂计算机.软件工程的博士师哥原创 双日练:NO.20200610 若将n个顶点e条弧的有向图采用邻接表存储,则拓扑排序算法的时间 ...

  3. JavaScript实现topologicalSort拓扑排序算法(附完整源码)

    JavaScript实现topologicalSort拓扑排序算法(附完整源码) Comparator.js完整源代码 LinkedListNode.js完整源代码 LinkedList.js完整源代 ...

  4. C++实现topological sort拓扑排序算法(附完整源码)

    C++实现topological sort拓扑排序算法 C++实现topological sort拓扑排序算法完整源码(定义,实现,main函数测试) C++实现topological sort拓扑排 ...

  5. C++使用kahn实现topological sort拓扑排序算法(附完整源码)

    C++使用kahn实现topological sort拓扑排序算法 C++使用kahn实现topological sort拓扑排序算法完整源码(定义,实现,main函数测试) C++使用kahn实现t ...

  6. 【数据结构】图的应用(普利姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、拓扑排序)

    最小生成树 什么是最小生成树 是一棵树 - 无回路 - |V|个顶点一定有|V|-1条边 是生成树 - 包含全部顶点 - |V|-1条边全在图里 贪心算法 什么是"贪":每一步都要 ...

  7. 【数据结构和算法】拓扑排序(附leetcode题 207/210 课程表)

    拓扑排序: 对于有向无环图,访问当前顶点时必须 保证指向该顶点的所有顶点已经访问过 作用: 1.得到一个[拓扑序](不唯一) 2.检测[有向图]是否有环:如果有拓扑排序则无环,否则有环 (如果存在环, ...

  8. 邻接表存储 - 拓扑排序算法

    拓扑排序:用下面的例子介绍------> ---------------------------------------------------------------------------- ...

  9. 图的深度优先搜索及拓扑排序

    本文将介绍图的深度优先搜索,并实现基于深度优先搜索的拓扑排序(拓扑排序适用于有向无环图,下面详细介绍). 1. 图的深度优先遍历要解决的问题 图的深度优先搜索与树的深度优先搜索类似,但是对图进行深度优 ...

最新文章

  1. 怎么形容智能冰激凌机器人_有关于形容描写冰激凌的句子及图片
  2. 思杰技术的论坛网址(转)
  3. 股票涨停之后该不该卖?
  4. mysql源代码安装_mysql源代码安装
  5. lede 内核 单 编_openwrt和lede有何区别?
  6. 汉字字符编码在线查询的网站
  7. 计算机一级最难考题,计算机一级试题
  8. 微众银行“梦见”区块链
  9. 2020年4月github上最热门项目-python
  10. 怎样安装2003服务器系统安装,Windows 2003系统详细安装教程图解
  11. linux调整逻辑卷大小,调整Linux逻辑卷大小
  12. FrontEnd笔记 -- Vue 核心
  13. 面试官问:为什么 Java 线程没有Running状态?我懵了
  14. MySQL数据库 日志管理、备份与恢复
  15. 游戏开发设计模式:单例模式
  16. PHP保存微信头像到本地
  17. 用Python分析了30000+《独行月球》影评数据,看看观众们怎么说~
  18. 2m带宽服务器多少个网站,2M带宽能撑起多少人访问?一文教会您所以带宽相关知识,以后选云服务器不求人...
  19. arduino低功耗模式_一起来看看新推出的Arduino开发板MKR WAN 1310
  20. L2-005 集合相似度(STL)

热门文章

  1. Java Math 反正弦asin反余弦acos函数使用注意事项
  2. 微信小程序毕业设计、基于微信小程序商城系统(后台php) 开题报告(基于微信小程序毕业设计题目选题课题)
  3. 让你的app体验更丝滑的11种方法!冲击手机应用榜单Top3指日可待
  4. html页面标题闪光字体,HTML最简单的文字闪烁代码
  5. Django知识点之urls.py路由设置
  6. 会议主持人的说话技巧,你知道吗?
  7. C#运用ajax实现updatepanel控件更新及弹窗
  8. OpenSSL密码库算法笔记——第1.2.2章 comba乘法
  9. RK3568平台开发系列讲解(视频篇)视频编码的工作原理
  10. SpringCloud 微服务分布式 应用笔记(三)