在linux下实现拓扑排序,数据结构——有向图(拓扑排序算法)

package zieckey.datastructure.study.graph;

/**

* 有方向图

*

* @author zieckey

*/

public class DirectedGraph

{

private final int    MAX_VERTS    = 20;

private Vertex[]    vertexList;        // array of vertices

private int[][]        adjMat;            // adjacency matrix

private int            nVerts;            // current number of vertices

private char[]        sortedArray;        // sorted vert labels

/**

* 默认构造函数 初始化邻接矩阵

*/

public DirectedGraph( )

{

vertexList = new Vertex[MAX_VERTS];

sortedArray = new char[MAX_VERTS];

// 图的邻接矩阵adjacency matrix

adjMat = new int[MAX_VERTS][MAX_VERTS];

nVerts = 0;

for ( int j = 0; j < MAX_VERTS; j++ )

{

// set adjacency

for ( int k = 0; k < MAX_VERTS; k++ )

{

adjMat[j][k] = 0;

}

}

}

/**

* 对有向图进行拓扑排序

*

* 无后继的顶点优先拓扑排序方法

* 1、思想方法

* 该方法的每一步均是输出当前无后继(即出度为0)的顶点。

* 对于一个DAG,按此方法输出的序列是逆拓扑次序。

* 因此设置一个栈(或向量)T来保存输出的顶点序列,即可得到拓扑序列。

* 若T是栈,则每当输出顶点时,只需做人栈操作,排序完成时将栈中顶点依次出栈即可得拓扑序列。

* 若T是向量,则将输出的顶点从T[n-1]开始依次从后往前存放,即可保证T中存储的顶点是拓扑序列。

*/

public void nonSuccFirstToplogicalSort()

{

int orig_nVerts = nVerts;

while(nVerts>0)

{

int delVertex = getNoSuccessorVertex();

if ( -1 == delVertex )

{

System.out.println("Error: This graph has cycles! It cannot be toplogical sorted.");

return;

}

sortedArray[nVerts-1] = vertexList[delVertex].label;

deleteVertex( delVertex );

}

System.out.print("Topologically sorted order: ");

for(int j=0; j

{

System.out.print( sortedArray[j] );

}

System.out.println("");

}

/**

* 找到没有后继节点的节点

* @return

*/

public int getNoSuccessorVertex()

{

boolean isEdge;

for ( int row = 0; row < nVerts; row++ )

{

isEdge = false;

for ( int column = 0; column < nVerts; column++ )

{

if ( adjMat[row][column]>0 )//大于0,表明有边指向其他点,说明有后继节点

{

isEdge = true;

break;                    //OK,继续下一个节点

}

}

if ( false == isEdge )//没有边,表明没有后继节点

{

return row;

}

}

return -1;

}

/**

* 删除一个节点

* @param delVertex

*/

public void deleteVertex( int delVertex )

{

if ( delVertex != nVerts-1 )//如果不是最后一个节点

{

//在节点列表中删除这个节点,所有后面的节点前移一格

for ( int i = delVertex; i < nVerts-1; i++ )

{

vertexList[i] = vertexList[i+1];

}

// 删除邻接矩阵的delVertex行和列,即所有后面的行和列都向前移动一格

// 所有delVertex行后的行,向上一个格

for ( int row = delVertex; row < nVerts - 1; row++ )

{

for ( int column = 0; column < nVerts; column++ )

{

adjMat[row][column] = adjMat[row + 1][column];

}

}

// 所有delVertex列后的列,向左一个格

for ( int column = delVertex; column < nVerts; column++ )

{

for ( int row = 0; row < nVerts - 1; row++ )

{

adjMat[row][column] = adjMat[row][column+1];

}

}

}

nVerts--;//减少一个节点

}

/**

* 添加一个节点

*

* @param lab

*/

public void addVertex( char lab ) // argument is label

{

vertexList[nVerts++ ] = new Vertex( lab );

}

/**

* 添加一条边

*

* @param start

* 起始点

* @param end

* 终点

*/

public void addEdge( int start, int end )

{

adjMat[start][end] = 1;

}

/**

* 添加一条边

*

* @param start

* 起始点

* @param end

* 终点

*/

public void addEdge( char startVertex, char endVertex )

{

int start = getIndexByLabel( startVertex );

int end = getIndexByLabel( endVertex );

if ( -1 != start && -1 != end )

{

adjMat[start][end] = 1;

}

}

/**

* 显示一个节点

*

* @param v

*/

public void displayVertex( int v )

{

System.out.print( vertexList[v].label );

}

public int getIndexByLabel( char lable )

{

for ( int i = 0; i < vertexList.length; i++ )

{

if ( lable == vertexList[i].label )

{

return i;

}

}

// 没有这个节点

return -1;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值