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 发布文章使用:只允许注册用户才可以访问!
随机推荐
- ES5 数据属性描述符和存取描述符
一.数据属性描述符 对象是一个属性集合,对象的基本特征是属性名(name)和属性值(value).ES5 增加了属性描述符,可以更细腻的控制属性的不同操作.属性描述符有 configurable.wr ...
- Ubuntu 部署Postgresql
安装组件 客户端安装 sudo apt-get install postgresql-client 服务器安装 sudo apt-get install postgresql postgresql-c ...
- audacity开源VS2013环境搭建
audacity是非常不错的音频开源,其中音频效果处理的种类很多,非常方便借鉴和研究. 但是audacity的界面库是使用wxWidgets(一个跨平台的界面库),配置过程中需要折腾一下. 1,首先去 ...
- [WPF系列]-基础 TextBlock
AUTOMATICALLY SHOWING TOOLTIPS ON A TRIMMED TEXTBLOCK (SILVERLIGHT + WPF)
- Java报表工具FineReport导出EXCEL的四种API
在实际的应用中会经常需要将数据导出成excel,导出的方式除原样导出还有分页导出.分页分sheet导出和大数据量导出.对于excel 2003版,由于限制了每个sheet的最大行数和列数,大数据量导出 ...
- 帆软报表FineReport数据库连接编码转换
1. 问题描述 数据库会以某种编码方式保存与读取数据,FineReport解析时默认使用GBK字符集,若数据库端编码与设计器端编码不一致时,就会导致中文及特殊字符的乱码. FineReport在定义数 ...
- Spring中的cglib动态代理
Spring中的cglib动态代理 cglib:Code Generation library, 基于ASM(java字节码操作码)的高性能代码生成包 被许多AOP框架使用 区别于JDK动态代理,cg ...
- 嵌入式Linux驱动学习之路(二十一)字符设备驱动程序总结和块设备驱动程序的引入
字符设备驱动程序 应用程序是调用C库中的open read write等函数.而为了操作硬件,所以引入了驱动模块. 构建一个简单的驱动,有一下步骤. 1. 创建file_operations 2. 申 ...
- [转]Windows平台下Makefile学习笔记
Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...
- BZOJ1856[SCOI2010]字符串
Description lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数.现在lxhgw ...