1. package graph;
  2.  
  3. import java.util.LinkedList;
  4. import java.util.Queue;
  5.  
  6. import thinkinjava.net.mindview.util.Stack;
  7.  
  8. //类名:Vertex
  9. //属性:
  10. //方法:
  11. class Vertex{
  12. public char label; //点的名称,如A
  13. public boolean wasVisited;
  14.  
  15. public Vertex(char lab){ //构造函数
  16. label = lab;
  17. wasVisited = false;
  18. }
  19. }
  20.  
  21. //类名:Graph
  22. //属性:
  23. //方法:
  24. class Graph{
  25. private final int MAX_VERTS = 20;
  26. private Vertex vertexList[]; //顶点列表数组
  27. private int adjMat[][]; //邻接矩阵
  28. private int nVerts; //当前的顶点
  29. private char sortedArray[];
  30.  
  31. public Graph(){ //构造函数
  32. vertexList = new Vertex[MAX_VERTS];
  33. adjMat = new int[MAX_VERTS][MAX_VERTS];
  34. nVerts = 0;
  35. for(int j=0;j<MAX_VERTS;j++){
  36. for(int k=0;k<MAX_VERTS;k++)
  37. adjMat[j][k] = 0;
  38. }
  39. sortedArray = new char[MAX_VERTS];
  40. }
  41.  
  42. public void addVertex(char lab){ //添加新的顶点,传入顶点的lab,并修改nVerts
  43. vertexList[nVerts++] = new Vertex(lab);
  44. }
  45.  
  46. public void addEdge(int start,int end){ //添加边,这里是无向图
  47. adjMat[start][end] = 1;
  48. //adjMat[end][start] = 1;
  49. }
  50.  
  51. public void displayVertex(int v){ //显示顶点
  52. System.out.print(vertexList[v].label);
  53. }
  54.  
  55. public int getAdjUnvisitedVertex(int v){ //返回一个和v邻接的未访问顶点
  56. for(int j=0;j<nVerts;j++)
  57. if(adjMat[v][j] == 1 && vertexList[j].wasVisited == false){
  58. return j;
  59. }
  60. return -1; //如果没有,返回-1
  61. }
  62.  
  63. public void dfs(){ //深度搜索
  64. Stack<Integer> theStack = new Stack<Integer>();
  65. vertexList[0].wasVisited = true;
  66. displayVertex(0);
  67. theStack.push(0); //把根入栈
  68.  
  69. while(!theStack.empty()){
  70. int v = getAdjUnvisitedVertex(theStack.peek());//取得一个和栈顶元素邻接的未访问元素
  71. if(v == -1) //如果没有和栈顶元素邻接的元素,就弹出这个栈顶
  72. theStack.pop();
  73. else{ //如果有这个元素,则输出这个元素,标记为已访问,并入栈
  74. vertexList[v].wasVisited = true;
  75. displayVertex(v);
  76. theStack.push(v);
  77. }
  78. }
  79. for(int j=0;j<nVerts;j++) //全部置为未访问
  80. vertexList[j].wasVisited = false;
  81. }
  82.  
  83. public void bfs(){ //广度搜索
  84. Queue<Integer> theQueue = new LinkedList<Integer>();
  85. vertexList[0].wasVisited = true;
  86. displayVertex(0);
  87. theQueue.offer(0); //把根入队列
  88. int v2;
  89.  
  90. while(!theQueue.isEmpty()){
  91. int v1 = theQueue.remove();//v1记录第1层的元素,然后记录第2层第1个元素...
  92.  
  93. while((v2=getAdjUnvisitedVertex(v1)) != -1){//输出所有和第1层邻接的元素,输出和第2层第1个元素邻接的元素...
  94. vertexList[v2].wasVisited = true;
  95. displayVertex(v2);
  96. theQueue.offer(v2);
  97. }
  98. }
  99.  
  100. for(int j=0;j<nVerts;j++) //全部置为未访问
  101. vertexList[j].wasVisited = false;
  102. }
  103.  
  104. public void mst(){ //基于深度搜索的最小生成树
  105. Stack<Integer> theStack = new Stack<Integer>();
  106. vertexList[0].wasVisited = true;
  107. theStack.push(0); //把根入栈
  108.  
  109. while(!theStack.empty()){
  110. int currentVertex = theStack.peek(); //记录栈顶元素,当有为邻接元素的时候,才会输出
  111. int v = getAdjUnvisitedVertex(theStack.peek());//取得一个和栈顶元素邻接的未访问元素
  112. if(v == -1) //如果没有和栈顶元素邻接的元素,就弹出这个栈顶
  113. theStack.pop();
  114. else{ //如果有这个元素,则输出这个元素,标记为已访问,并入栈
  115. vertexList[v].wasVisited = true;
  116. theStack.push(v);
  117.  
  118. displayVertex(currentVertex);
  119. displayVertex(v);
  120. System.out.println();
  121. }
  122. }
  123. for(int j=0;j<nVerts;j++) //全部置为未访问
  124. vertexList[j].wasVisited = false;
  125. }
  126.  
  127. public int noSuccessors(){ //使用邻接矩阵找到没有后继的顶点,有后继顶点返回行数,没有返回-1
  128. boolean isEdge;
  129.  
  130. for(int row=0;row<nVerts;row++){//从第1行开始
  131. isEdge = false;
  132. for(int col=0;col<nVerts;col++){//如果某一行某一列为1,返回这个行的行数
  133. if(adjMat[row][col] > 0){
  134. isEdge = true;
  135. break;
  136. }
  137. }
  138. if(!isEdge)
  139. return row;
  140. }
  141. return -1;
  142. }
  143.  
  144. public void moveRowUp(int row,int length){
  145. for(int col=0;col<length;col++)
  146. adjMat[row][col] = adjMat[row+1][col];
  147. }
  148.  
  149. public void moveColLeft(int col,int length){
  150. for(int row=0;row<length;row++)
  151. adjMat[row][col] = adjMat[row][col+1];
  152. }
  153.  
  154. public void deleteVertex(int delVert){
  155. if(delVert != nVerts-1){
  156. for(int j=delVert;j<nVerts-1;j++)//在数组中去掉这个顶点
  157. vertexList[j] = vertexList[j+1];
  158. for(int row=delVert;row<nVerts-1;row++)//在邻接矩阵中把删除的这一行下的所有行上移
  159. moveRowUp(row,nVerts);
  160. for(int col=delVert;col<nVerts-1;col++)//在邻接矩阵中把删除的这一列下的所有列左移
  161. moveColLeft(col,nVerts-1);
  162. }
  163. nVerts--;
  164. }
  165.  
  166. public void topo(){ //拓扑排序,必须在无环的有向图中进行,必须在有向图中
  167. int orig_nVerts = nVerts; //记录有多少个顶点
  168.  
  169. while(nVerts > 0){
  170. int currentVertex = noSuccessors();
  171. if(currentVertex == -1){
  172. System.out.println("错误:图含有环!");
  173. return;
  174. }
  175. sortedArray[nVerts-1] = vertexList[currentVertex].label;
  176. deleteVertex(currentVertex);
  177. }
  178. System.out.println("拓扑排序结果:");
  179. for(int j=0;j<orig_nVerts;j++)
  180. System.out.println(sortedArray[j]);
  181.  
  182. }
  183.  
  184. }
  185.  
  186. public class graph_demo {
  187.  
  188. public static void main(String[] args) {
  189. // TODO 自动生成的方法存根
  190. Graph theGraph = new Graph();
  191. theGraph.addVertex('A'); //数组元素0
  192. theGraph.addVertex('B'); //数组元素1
  193. theGraph.addVertex('C'); //数组元素2
  194. theGraph.addVertex('D'); //数组元素3
  195. theGraph.addVertex('E'); //数组元素4
  196.  
  197. // theGraph.addEdge(0, 1); //AB
  198. // theGraph.addEdge(1, 2); //BC
  199. // theGraph.addEdge(0, 3); //AD
  200. // theGraph.addEdge(3, 4); //DE
  201.  
  202. // System.out.println("dfs访问的顺序:");
  203. // theGraph.dfs();
  204. // System.out.println();
  205. //
  206. // System.out.println("bfs访问的顺序:");
  207. // theGraph.bfs();
  208.  
  209. // theGraph.addEdge(0, 1); //AB
  210. // theGraph.addEdge(0, 2); //AC
  211. // theGraph.addEdge(0, 3); //AD
  212. // theGraph.addEdge(0, 4); //AE
  213. // theGraph.addEdge(1, 2); //BC
  214. // theGraph.addEdge(1, 3); //BD
  215. // theGraph.addEdge(1, 4); //BE
  216. // //theGraph.addEdge(2, 3); //CD
  217. // //theGraph.addEdge(2, 4); //CE
  218. // theGraph.addEdge(3, 4); //DE
  219.  
  220. // System.out.println("最小生成树:");
  221. // theGraph.mst();
  222.  
  223. theGraph.addVertex('F'); //数组元素5
  224. theGraph.addVertex('G'); //数组元素6
  225. theGraph.addVertex('H'); //数组元素6
  226.  
  227. theGraph.addEdge(0, 3); //AD
  228. theGraph.addEdge(0, 4); //AE
  229. theGraph.addEdge(1, 4); //BE
  230. theGraph.addEdge(2, 5); //CF
  231. theGraph.addEdge(3, 6); //DG
  232. theGraph.addEdge(4, 6); //EG
  233. theGraph.addEdge(5, 7); //FH
  234. theGraph.addEdge(6, 7); //GH
  235.  
  236. theGraph.topo();
  237. }
  238.  
  239. }

Java排序算法——拓扑排序的更多相关文章

  1. AOV网络和Kahn算法拓扑排序

    1.AOV与DAG 活动网络可以用来描述生产计划.施工过程.生产流程.程序流程等工程中各子工程的安排问题.   一般一个工程可以分成若干个子工程,这些子工程称为活动(Activity).完成了这些活动 ...

  2. 经典排序算法 - 高速排序Quick sort

    经典排序算法 - 高速排序Quick sort 原理,通过一趟扫描将要排序的数据切割成独立的两部分,当中一部分的全部数据都比另外一部分的全部数据都要小,然后再按此方法对这两部分数据分别进行高速排序,整 ...

  3. 排序算法--希尔排序(Shell Sort)_C#程序实现

    排序算法--希尔排序(Shell Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难 ...

  4. 排序算法--选择排序(Selection Sort)_C#程序实现

    排序算法--选择排序(Selection Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来 ...

  5. 数据结构和算法(Golang实现)(20)排序算法-选择排序

    选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...

  6. 数据结构和算法(Golang实现)(22)排序算法-希尔排序

    希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...

  7. 使用 js 实现十大排序算法: 桶排序

    使用 js 实现十大排序算法: 桶排序 桶排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  8. 使用 js 实现十大排序算法: 计数排序

    使用 js 实现十大排序算法: 计数排序 计数排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  9. 使用 js 实现十大排序算法: 希尔排序

    使用 js 实现十大排序算法: 希尔排序 希尔排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

随机推荐

  1. Mysql有用的面试题

    A.一道SQL语句面试题,关于group by表内容:2005-05-09 胜2005-05-09 胜2005-05-09 负2005-05-09 负2005-05-10 胜2005-05-10 负2 ...

  2. mysql编码格式设置

    两个地方能影响到mysql的编码格式 ①.[mysql]下default-character-set=GBK//指的是客户端输入的内容的编码(GBK只是支持中英文)②.[mysqld]下# The d ...

  3. 【推荐】CentOS安装Tomcat-7.0.57+启动配置+安全配置+性能配置

    注:以下所有操作均在CentOS 6.5 x86_64位系统下完成. #准备工作# 在安装Tomcat之前,请确保已经安装了JDK-1.7环境,具体见<CentOS安装JDK-1.7>. ...

  4. java操作hdfs实例

    环境:window7+eclipse+vmware虚拟机+搭建好的hadoop环境(master.slave01.slave02) 内容:主要是在windows环境下,利用eclipse如何来操作hd ...

  5. shell parameter expansitions

    type testtype -a test math calculate:echo $((1+2*3)) parameter expansition:bash-4 introduced feature ...

  6. Spring AOP深入剖析

    一.通过代理工厂模式配置通知 ①.前置通知.后置通知: 定义某接口:ISomeService,并自定义方法 public interface ISomeService { public void tr ...

  7. git提交时支持文件名大小写的修改

    在windows环境下,git提交文件时,默认对文件名大小写不敏感,若修改了文件名字的大小写,可能会导致提交时没有记录,文件名修改不成功.网上搜集了几种解决方法,现总结下: 1. 修改git conf ...

  8. ajax 请求另一个html页面的指定的一部分 加载到本页面div

    $.ajax( { url: url, //这里是静态页的地址 type: "GET", //静态页用get方法,否则服务器会抛出405错误 success: function(d ...

  9. windows7配置Nginx+php+mysql教程

    windows7配置Nginx+php+mysql教程 最近在学习php,想把自己的学习经历记录下来,并写一些经验,仅供参考交流.此文适合那些刚刚接触php,想要学习并想要自己搭建Nginx+php+ ...

  10. 2016-2017-2 《Java程序设计》预备作业1 总结

    2016-2017-2 <Java程序设计>预备作业1 总结 预备作业01:你期望的师生关系是什么见https://edu.cnblogs.com/campus/besti/2016-20 ...