Java排序算法——拓扑排序




package graph; import java.util.LinkedList;
import java.util.Queue; import thinkinjava.net.mindview.util.Stack; //类名:Vertex
//属性:
//方法:
class Vertex{
public char label; //点的名称,如A
public boolean wasVisited; public Vertex(char lab){ //构造函数
label = lab;
wasVisited = false;
}
} //类名:Graph
//属性:
//方法:
class Graph{
private final int MAX_VERTS = 20;
private Vertex vertexList[]; //顶点列表数组
private int adjMat[][]; //邻接矩阵
private int nVerts; //当前的顶点
private char sortedArray[]; public Graph(){ //构造函数
vertexList = new Vertex[MAX_VERTS];
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for(int j=0;j<MAX_VERTS;j++){
for(int k=0;k<MAX_VERTS;k++)
adjMat[j][k] = 0;
}
sortedArray = new char[MAX_VERTS];
} public void addVertex(char lab){ //添加新的顶点,传入顶点的lab,并修改nVerts
vertexList[nVerts++] = new Vertex(lab);
} public void addEdge(int start,int end){ //添加边,这里是无向图
adjMat[start][end] = 1;
//adjMat[end][start] = 1;
} public void displayVertex(int v){ //显示顶点
System.out.print(vertexList[v].label);
} public int getAdjUnvisitedVertex(int v){ //返回一个和v邻接的未访问顶点
for(int j=0;j<nVerts;j++)
if(adjMat[v][j] == 1 && vertexList[j].wasVisited == false){
return j;
}
return -1; //如果没有,返回-1
} public void dfs(){ //深度搜索
Stack<Integer> theStack = new Stack<Integer>();
vertexList[0].wasVisited = true;
displayVertex(0);
theStack.push(0); //把根入栈 while(!theStack.empty()){
int v = getAdjUnvisitedVertex(theStack.peek());//取得一个和栈顶元素邻接的未访问元素
if(v == -1) //如果没有和栈顶元素邻接的元素,就弹出这个栈顶
theStack.pop();
else{ //如果有这个元素,则输出这个元素,标记为已访问,并入栈
vertexList[v].wasVisited = true;
displayVertex(v);
theStack.push(v);
}
}
for(int j=0;j<nVerts;j++) //全部置为未访问
vertexList[j].wasVisited = false;
} public void bfs(){ //广度搜索
Queue<Integer> theQueue = new LinkedList<Integer>();
vertexList[0].wasVisited = true;
displayVertex(0);
theQueue.offer(0); //把根入队列
int v2; while(!theQueue.isEmpty()){
int v1 = theQueue.remove();//v1记录第1层的元素,然后记录第2层第1个元素... while((v2=getAdjUnvisitedVertex(v1)) != -1){//输出所有和第1层邻接的元素,输出和第2层第1个元素邻接的元素...
vertexList[v2].wasVisited = true;
displayVertex(v2);
theQueue.offer(v2);
}
} for(int j=0;j<nVerts;j++) //全部置为未访问
vertexList[j].wasVisited = false;
} public void mst(){ //基于深度搜索的最小生成树
Stack<Integer> theStack = new Stack<Integer>();
vertexList[0].wasVisited = true;
theStack.push(0); //把根入栈 while(!theStack.empty()){
int currentVertex = theStack.peek(); //记录栈顶元素,当有为邻接元素的时候,才会输出
int v = getAdjUnvisitedVertex(theStack.peek());//取得一个和栈顶元素邻接的未访问元素
if(v == -1) //如果没有和栈顶元素邻接的元素,就弹出这个栈顶
theStack.pop();
else{ //如果有这个元素,则输出这个元素,标记为已访问,并入栈
vertexList[v].wasVisited = true;
theStack.push(v); displayVertex(currentVertex);
displayVertex(v);
System.out.println();
}
}
for(int j=0;j<nVerts;j++) //全部置为未访问
vertexList[j].wasVisited = false;
} public int noSuccessors(){ //使用邻接矩阵找到没有后继的顶点,有后继顶点返回行数,没有返回-1
boolean isEdge; for(int row=0;row<nVerts;row++){//从第1行开始
isEdge = false;
for(int col=0;col<nVerts;col++){//如果某一行某一列为1,返回这个行的行数
if(adjMat[row][col] > 0){
isEdge = true;
break;
}
}
if(!isEdge)
return row;
}
return -1;
} public void moveRowUp(int row,int length){
for(int col=0;col<length;col++)
adjMat[row][col] = adjMat[row+1][col];
} public void moveColLeft(int col,int length){
for(int row=0;row<length;row++)
adjMat[row][col] = adjMat[row][col+1];
} public void deleteVertex(int delVert){
if(delVert != nVerts-1){
for(int j=delVert;j<nVerts-1;j++)//在数组中去掉这个顶点
vertexList[j] = vertexList[j+1];
for(int row=delVert;row<nVerts-1;row++)//在邻接矩阵中把删除的这一行下的所有行上移
moveRowUp(row,nVerts);
for(int col=delVert;col<nVerts-1;col++)//在邻接矩阵中把删除的这一列下的所有列左移
moveColLeft(col,nVerts-1);
}
nVerts--;
} public void topo(){ //拓扑排序,必须在无环的有向图中进行,必须在有向图中
int orig_nVerts = nVerts; //记录有多少个顶点 while(nVerts > 0){
int currentVertex = noSuccessors();
if(currentVertex == -1){
System.out.println("错误:图含有环!");
return;
}
sortedArray[nVerts-1] = vertexList[currentVertex].label;
deleteVertex(currentVertex);
}
System.out.println("拓扑排序结果:");
for(int j=0;j<orig_nVerts;j++)
System.out.println(sortedArray[j]); } } public class graph_demo { public static void main(String[] args) {
// TODO 自动生成的方法存根
Graph theGraph = new Graph();
theGraph.addVertex('A'); //数组元素0
theGraph.addVertex('B'); //数组元素1
theGraph.addVertex('C'); //数组元素2
theGraph.addVertex('D'); //数组元素3
theGraph.addVertex('E'); //数组元素4 // theGraph.addEdge(0, 1); //AB
// theGraph.addEdge(1, 2); //BC
// theGraph.addEdge(0, 3); //AD
// theGraph.addEdge(3, 4); //DE // System.out.println("dfs访问的顺序:");
// theGraph.dfs();
// System.out.println();
//
// System.out.println("bfs访问的顺序:");
// theGraph.bfs(); // theGraph.addEdge(0, 1); //AB
// theGraph.addEdge(0, 2); //AC
// theGraph.addEdge(0, 3); //AD
// theGraph.addEdge(0, 4); //AE
// theGraph.addEdge(1, 2); //BC
// theGraph.addEdge(1, 3); //BD
// theGraph.addEdge(1, 4); //BE
// //theGraph.addEdge(2, 3); //CD
// //theGraph.addEdge(2, 4); //CE
// theGraph.addEdge(3, 4); //DE // System.out.println("最小生成树:");
// theGraph.mst(); theGraph.addVertex('F'); //数组元素5
theGraph.addVertex('G'); //数组元素6
theGraph.addVertex('H'); //数组元素6 theGraph.addEdge(0, 3); //AD
theGraph.addEdge(0, 4); //AE
theGraph.addEdge(1, 4); //BE
theGraph.addEdge(2, 5); //CF
theGraph.addEdge(3, 6); //DG
theGraph.addEdge(4, 6); //EG
theGraph.addEdge(5, 7); //FH
theGraph.addEdge(6, 7); //GH theGraph.topo();
} }
Java排序算法——拓扑排序的更多相关文章
- AOV网络和Kahn算法拓扑排序
1.AOV与DAG 活动网络可以用来描述生产计划.施工过程.生产流程.程序流程等工程中各子工程的安排问题. 一般一个工程可以分成若干个子工程,这些子工程称为活动(Activity).完成了这些活动 ...
- 经典排序算法 - 高速排序Quick sort
经典排序算法 - 高速排序Quick sort 原理,通过一趟扫描将要排序的数据切割成独立的两部分,当中一部分的全部数据都比另外一部分的全部数据都要小,然后再按此方法对这两部分数据分别进行高速排序,整 ...
- 排序算法--希尔排序(Shell Sort)_C#程序实现
排序算法--希尔排序(Shell Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难 ...
- 排序算法--选择排序(Selection Sort)_C#程序实现
排序算法--选择排序(Selection Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来 ...
- 数据结构和算法(Golang实现)(20)排序算法-选择排序
选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...
- 数据结构和算法(Golang实现)(22)排序算法-希尔排序
希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...
- 使用 js 实现十大排序算法: 桶排序
使用 js 实现十大排序算法: 桶排序 桶排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- 使用 js 实现十大排序算法: 计数排序
使用 js 实现十大排序算法: 计数排序 计数排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- 使用 js 实现十大排序算法: 希尔排序
使用 js 实现十大排序算法: 希尔排序 希尔排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
随机推荐
- spark dataframe unionall
今天本来想写一个spark dataframe unionall的demo,由于粗心报下面错误: Exception in thread "main" org.apache.spa ...
- [转载]python中的sys模块(二)
#!/usr/bin/python # Filename: using_sys.py import sys print 'The command line arguments are:' for i ...
- POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]
Father Christmas flymouse Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 3241 Accep ...
- org.hibernate.HibernateException: No Session found for current thread
spring.springmvc和hibernate整合 在sessionFactory.getCurrentSession()时,出现以下异常 No Session found for curren ...
- sicily 猴子选大王
题目描述 猴子选大王,有N只猴子,从1-N进行编号.它们按照编号的顺时针方向,排成一个圆圈,然后从第一只猴子开始报数.第一只猴子报1,以后每只猴子报的数字都是它前面猴子所报数字加1.如果一只猴子报的数 ...
- ThreadLocal()理解
在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. 当使用 ...
- Java中的instanceof关键字
instanceof是Java的一个二元操作符,和==,>,<是同一类东东.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回boo ...
- virtual memory exhausted: Cannot allocate memory
~$free total used free shared buffers cached Mem: 1017832 784328 233504 356 12844 14692 -/+ buffers/ ...
- 上传本地代码到github
第一步:建立git仓库 cd到你的本地项目根目录下,执行git命令git init第二步:将项目的所有文件添加到仓库中git add .如果想添加某个特定的文件,只需把.换成特定的文件名即可第三步:将 ...
- Xcode使错误停在出错代码上
创建异常断点 依次选择“Debug”>“Breakpoints”>“Create Execption Breakpoint”