拓扑排序作为图的应用,了解拓扑排序必须首先了解AOV图。

AOV网表示一个有向图中顶点,用弧表示顶点之间的优先关系。如下图所示,在AOV网中,若从顶点vi到顶点vj之间存在一条有向路径,则称顶点vi为顶点vj的前驱,顶点vj为顶点vi的后继。注意,AOV图不能有回路,否则会将序列陷入死循环,称为死锁。

进行拓扑排序,一般步骤如下:

<1>在AOV网中选择一个入度为0的顶点

<2>在AOV网中删除此顶点及其相连的有向边

<3>重复步骤<1>和<2>,直到AOV网中没有入度为0的顶点为止

由于拓扑排序具有不确定性,因此经过排序的序列应人而异,不过大多序列的逻辑关系能够走通。

程序如下:

package 拓扑排序;
/*
 * 在AOV网中寻找拓扑排序序列的步骤如下:
 * <1>在AOV网中选择一个入度为0的顶点
 * <2>从AOV往中删除此顶点以及与其相连的有向边
 * <3>重复步骤<1>和<2>。直到AOV网中没有入度为0的顶点
 */
public class TopoSort {
 /**
  * @author 刘雁冰
  * @date 2015-02-14 20:22
  */
 /*
  * Max:定义顶点的最大容量为100
  * ver:使用内部Vertexs类创建一个数组ver,存储顶点的关键字
  * map:AOV网的邻接矩阵表
  * n:顶点的数量
  * topoSort:存储最终得到的序列
  */
 static int Max=100;
 static Vertexs ver[];
 static int map[][];
 static int n;
 static char topoSort[];
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  ver=new Vertexs[Max];
  map=new int[Max][Max];
  n=0;
  topoSort=new char[Max];
  //初始化邻接矩阵
  for(int i=0;i<Max;i++){
   for(int j=0;j<Max;j++){
    map[i][j]=0;
   }
  }
  TopoSort ts=new TopoSort();
  //读入AOV网顶点的关键字
  ts.addVertex('A');
  ts.addVertex('B');
  ts.addVertex('C');
  ts.addVertex('D');
  ts.addVertex('E');
  ts.addVertex('F');
  ts.addVertex('G');
  ts.addVertex('H');
  ts.addVertex('I');
  ts.addVertex('J');
  ts.addVertex('K');
  ts.addVertex('L');
  //读入AOV网边的连接信息,由于是有向图,只需读入一次
  ts.addEdge(0, 1);
  ts.addEdge(0, 3);
  ts.addEdge(0, 10);
  ts.addEdge(1, 10);
  ts.addEdge(2, 3);
  ts.addEdge(2, 4);
  ts.addEdge(2, 5);
  ts.addEdge(3, 7);
  ts.addEdge(5, 7);
  ts.addEdge(5, 6);
  ts.addEdge(5, 8);
  ts.addEdge(6, 8);
  ts.addEdge(6, 9);
  ts.addEdge(10, 11);
  ts.addEdge(11, 9);
  ts.addEdge(11, 6);
  ts.topoSort();
 }
 //构造顶点关键字数组
 public void addVertex(char v){
  ver[n++]=new Vertexs(v);
 }
 //构造边的邻接矩阵
 public void addEdge(int start,int end){
  map[start][end]=1;
 }
 public void topoSort(){
  //num:顶点数量n要进行递减,因此起始存入num,作为输出序列遍历使用
  //isEdge:判定该边是否相连
  int num=n;
  boolean isEdge;
  while(n>0){
   //选取一个入度为0的顶点
   int currVer=0;
   //遍历邻接矩阵
   for(int row=0;row<n;row++){
    isEdge=false;
    for(int col=0;col<n;col++){
     if(map[row][col]>0)
      isEdge=true;
    }
    //抽取邻接边表中没有出度的顶点(将邻接表行数赋值给当前顶点)
    if(!isEdge)
     currVer=row;
   }
   //将没有出度的顶点存入序列结果最后的位置
   topoSort[n-1]=ver[currVer].value;
  /*
   *  删除顶点操作
   * 当前顶点不为最后顶点时进行
   */
   if(currVer!=n-1){
    //顶点关键字数组往后移动一位
    for(int i=currVer;i<n;i++)
     ver[i]=ver[i+1];
    /*
     * 移动邻接表行列,覆盖原值
     */
    //邻接表行数往后移动一位(向右移动)
    for(int row=currVer;row<n-1;row++)
     for(int col=0;col<n;col++)
      map[row][col]=map[row+1][col];
    //邻接表列数往后移动一位(向左移动)
    for(int col=currVer;col<n-1;col++)
     for(int row=0;row<n;row++)
      map[row][col]=map[row][col+1];
   }
   n--;   //下一个顶点
  }
  //输出结果
  System.out.println("该图的拓扑排序序列为:");
  for(int i=0;i<num;i++){
  }
 }
}
class Vertexs{
 public char value;
 public Vertexs(char v){
  value=v;
 }
}

测试结果如下:

你可能感兴趣的内容
Java序列化与static 收藏,3246 浏览
0条评论

dexcoder

这家伙太懒了 <( ̄ ﹌  ̄)>
Owner