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排序算法——拓扑排序的更多相关文章

  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. Spark官方文档 - 中文翻译

    Spark官方文档 - 中文翻译 Spark版本:1.6.0 转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述(Overview) 2 引入Spark(Linki ...

  2. 烂泥:Postfix邮件服务器搭建之准备工作

    说实话,Postfix邮件服务器的搭建是一件很麻烦的事情,需要各种软件之间的配置和调试.在写这篇文章之前,我也是搭建测试了不下于10次才算把整个流程给走通,今天刚好有时间把整个搭建过程记录下来. 在正 ...

  3. android intent 传递list或者对象

    (转:http://www.cnblogs.com/lee0oo0/archive/2012/09/24/2699805.html) 方法一: 如果单纯的传递List<String> 或者 ...

  4. 《小白的CFD之旅》招募写手

    <小白的CFD之旅>系列招募写手. 由于工作繁忙,<小白的CFD之旅>系列更新缓慢,现招募志愿者写手.这是一个分享平台,欢迎各位愿意分享自己CFD学习经历的朋友们. <小 ...

  5. 关于mysql数据库插入数据,不能插入中文和出现中文乱码问题

    首先,推荐一篇博客:http://www.cnblogs.com/sunzn/archive/2013/03/14/2960248.html 当时,我安装完mysql数据库后,新建一个数据库后插入数据 ...

  6. OpenStack 企业私有云的若干需求(5):主流硬件支持、云快速交付 和 SLA 保证

    本系列会介绍OpenStack 企业私有云的几个需求: 自动扩展(Auto-scaling)支持 多租户和租户隔离 (multi-tenancy and tenancy isolation) 混合云( ...

  7. Namesilo 管理域名教程

    在NameSilo注册域名之后,我们要做的就是开始对域名进行日常管理应用.大家可以参照下面这个Namesilo域名管理图文教程进行相应的操作. 1. 登录域名管理列表并选择相应域名 首先,登录Name ...

  8. 电脑控制Android设备的软件——Total Control

    最早开始搞Android开发时,为了调试方便,想找一个Android下的远程控制软件,支持在电脑端远程控制和同步显示Android设备.先后试了360手机助手.Mobizen.Vysor和Mirror ...

  9. 由于log太多导致ubuntu硬盘空间满了,进入不了系统解决办法

    具体现象是在图形界面输入用户名和密码之后,再次提示需要输入用户名和密码. 步骤一:按快捷键进入命令行界面.ctrl+alt+f1. 步骤二:清空文件 clear log cd /var/log sud ...

  10. Python-18-Django 基础篇

    1. Web 框架介绍 具体介绍Django之前,必须先介绍WEB框架等概念. Web框架:通俗地讲,就是别人已经设定好的一个web网站模板,你学习它的规则,然后「填空」或「修改」成你自己需要的样子. ...