(1)、有向圖,邊是有方向的。
鄰接矩陣表示方法上下三角形是不對稱的。在添加一條邊是只需要一條語句,
//添加一個邊
public void addEdge(int start,int end){
adjMat[start][end] = 1;
}
(2)、有向圖的演算法-拓撲排序
有向圖的應用,某些項目或者事件必須按照特定的順序排序或發生。
比如大學課程安排,要想得到學位需要必修那些課程。每年的課程都按先後關係排序,全部必修完畢,最後才能答辯,拿到學位。
拓撲排序的步驟:
(1)、找到一個沒有後繼的頂點(如果有一條邊從A指向B,那麼B是A的後繼)。
(2)、刪除這個頂點,在列表的前面插入頂點的標記。
(3)、重複步驟1和2.直到所有的頂點都刪除。這時列表顯示的頂點順序就是拓撲排序的結果。
環:環圖是不能進行拓撲排序的,如果有N個頂點的有向圖有超過N-1條邊,那麼必定存在環。
Graph_topo.java
package com.mapbar.structure;/** * * Class Graph_topo * * Description 有向圖的拓撲排序 * * Company mapbar * * author Chenll E-mail: Chenll@mapbar.com * * Version 1.0 * * Date 2011-11-17 下午03:38:27 *///定義節點class Vertex{public char label;public boolean isVisited;public Vertex(char label){this.label = label;this.isVisited = false;}}public class Graph_topo {//頂點數組private Vertex[] vArr;//定義鄰接矩陣private int[][] adjMat; //頂點的最大數目 private int maxSize; //當前頂點 下標 private int currVertex; private char[] sortedArr; //構造方法 public Graph_topo(int maxSize){ sortedArr = new char[maxSize]; this.maxSize = maxSize; vArr = new Vertex[maxSize]; adjMat = new int[maxSize][maxSize]; for (int i = 0; i<adjMat.length; i++){ for(int j = 0; j<adjMat.length; j++){ adjMat[i][j] = 0; } } currVertex = 0; } //添加一個頂點 public void addVertex(char label){ vArr[currVertex++] = new Vertex(label); } //添加一個邊 public void addEdge(int start,int end){ adjMat[start][end] = 1; } //顯示一個頂點 public void disVertex(int v){ System.out.print(vArr[v].label+","); } //拓撲排序 public void topo(){ int orig_nVert = currVertex; while(currVertex>0){ int cuVertex = noSuc(); if(currVertex==-1){ System.out.println("圖中有環路,不能進行拓撲排序"); return; } sortedArr[currVertex-1] = vArr[cuVertex].label; deleteVertex(cuVertex); } disAllVertex(orig_nVert); } //找一個沒有後繼結點 public int noSuc(){ boolean isEdge; for(int i = 0; i<currVertex; i++){ isEdge = false; for(int j = 0; j<currVertex; j++){ if(adjMat[i][j]>0){ isEdge = true; break; } } if(!isEdge){ return i; } } return -1; } //刪除頂點,後面的頂點向前移動,同時行和列從矩陣中刪除,下面的行和右邊的列 public void deleteVertex(int delV){ if(delV != currVertex-1){ //刪除頂點 for(int j = delV; j<currVertex; j++){ vArr[j] = vArr[j+1]; } //刪除頂點所在的鄰接矩陣 //上移 for(int row = delV; row<currVertex-1; row++){ for(int col = 0; col<currVertex;col++){ adjMat[row][col] = adjMat[row+1][col]; } } //左移 for(int col = delV; col<currVertex-1; col++){ for(int row = 0; row<currVertex;row++){ adjMat[row][col] = adjMat[row][col+1]; } } } currVertex--; } //顯示拓撲排序的結果public void disAllVertex(int org_length){for(int j = 0; j<org_length; j++){System.out.print(sortedArr[j]+",");}} //主調函數 public static void main(String[] args){ Graph_topo g = new Graph_topo(10); g.addVertex('a'); g.addVertex('b'); g.addVertex('c'); g.addVertex('d'); g.addVertex('e'); g.addVertex('f'); g.addEdge(0,1); g.addEdge(0,2); g.addEdge(1,3); g.addEdge(4,5); g.addEdge(5,1); g.topo(); }}
output:
e,f,a,b,d,c,