Java实现AOV图的拓扑排序

c6g3 10年前

拓扑排序作为图的应用,了解拓扑排序必须首先了解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;   }  }


测试结果如下: