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 发布文章使用:只允许注册用户才可以访问!
随机推荐
- c#获取时间
DateTime.Now.AddDays(10).ToShortDateString().ToString() addDays(整数) 一天前DateTime.Now.AddDays(-1).ToSh ...
- mysql 常用sql
1.查询数据库.表的情况 show engines; #数据库的存储引擎show create TABLE User_Base_Info;#显示create table的sql语句show table ...
- linux文件拼接命令 paste
paste [文件名1 [文件名2] --] [选项] -s 把文件以行的方式拼接 -d 制定分隔符,默认以制表符分隔 [root@dagege ~]# >.txt [root@dagege ~ ...
- linux中的输入从定向和输出重定向
linux的标准的输入和输出为如下 我们在 linux中执行命令时,命令默认输出到console中,很多时候我们需要将命令输出到其他设备上如最常见的就文件中去,或者重文件中输入.那这时候就需要用到li ...
- java md5
需求是,上传文件到HDFS,然后生成同名的MD5文件,基本示例如下: public static String getMD5(InputStream inputStream) { byte[] buf ...
- C#学习笔记-输入数据判断(int、double、string)
代码: using System; using System.Windows.Forms; namespace CheckInput { public partial class Form1 : Fo ...
- 2016.10.29 清北学堂NOIP冲刺班Day1 AM 考试总结
成绩:满分300,我得了200, 1:90//前两个题目都是模拟,没用到什么其他算法,第一题有可能少考虑了一点细节 2:100 3:10//感觉是个DP,但是毫无思路,只打了个普通背包,10分而已. ...
- ZBrush中的动态网格该怎么进行运用
DynaMesh是ZBrush最新的基础模型创建工具,该命令用于基本模型的起稿到中模的制作.使用DynaMesh完全不启用考虑模型的拓扑,可以从一个图形拉扯出整个模型的分支,本文将以一个实例简单介绍Z ...
- struts2案例
Struts 2是一个MVC框架,以WebWork框架的设计思想为核心,吸收了Struts 1的部分优点.Struts 2拥有更加广阔的前景,自身功能强大,还对其他框架下开发的程序提供很好的兼容性.下 ...
- Hibernate对象标识符
Hibernate提供的内置标识符生成器 Java语言按内存地址来识别或区分同一个类的不同对象,而关系数据库按主键来识别或区分同一个表的不同记录.Hibernate使用OID(对象标识符)来统一两者之 ...