图的数据结构组成成分,包括了顶点,边,以及它们之间的连接关系。邻接矩阵是一种采用大小为V*V的矩阵Adj来表示点和边的关系的。其中矩阵的值为布尔值,如果两个点i,j之间存在一条边,则Adj[i][j] = 1。
深度优先搜索,类似于树的前序遍历,本质上也是用堆栈来实现。应用包括了:拓扑排序,查找连通分量,解决类似迷宫的问题等。
宽度优先搜索,类似于树的层次遍历,本质上是用队列来实现。应用包括了:检测死锁,计算作业的流水线等。
顶点类Vertex实现如下:
public class Vertex {
public char label;
public boolean visited;
public Vertex(char lab){
label = lab;
this.visited = false;
}
}
Graph类如下,此处省略堆栈与队列的实现细节。
public class Graph {
private final int maxVertices = 20;//最大的顶点数量
private Vertex vertexList[];
private int adjMatrix[][]; //邻接矩阵
private int VertexCount;
private Stack<Integer> theStack; //堆栈,为了DFS
private Queue<Integer> theQueue = new LinkedList<Integer>(); //队列,为了层次遍历
public Graph(){
vertexList = new Vertex[maxVertices];
adjMatrix = new int[maxVertices][maxVertices];
VertexCount = 0;
for(int y=0 ; y<maxVertices; y++)
for(int x=0;x<maxVertices;x++)
adjMatrix[x][y] = 0;
theStack = new Stack<Integer>();
}
public void addVertex(char lab){ //加入顶点
vertexList[VertexCount++] = new Vertex(lab);
}
public void addEdge(int start, int end){ //加入边
adjMatrix[start][end] = 1;
adjMatrix[end][start] = 1;
}
public void DisplayVertex(int v){
System.out.println(vertexList[v].label);
}
public void dfs(){ //深度优先遍历
vertexList[0].visited = true;
DisplayVertex(0);
theStack.push(0);
while(!theStack.isEmpty()){
//获得一个未访问的邻接顶点,压入堆栈
int v = getAdjUnvisitedVertex(theStack.peek()); //获得一个未访问的邻接顶点
if(v==-1)
theStack.pop(); //回溯
else{
vertexList[v].visited = true;
DisplayVertex(v);
theStack.push(v); //记录已访问的顶点
}
}
for(int j=0;j<VertexCount;j++) //将访问标记初始化
vertexList[j].visited = false;
}
public void bfs(){
vertexList[0].visited = true;
DisplayVertex(0);
theQueue.offer(0);
int v2;
while(!theQueue.isEmpty()){
int v1 = theQueue.remove();
while((v2=getAdjUnvisitedVertex(v1))!=-1){ //将v2所有的邻接点都压入队列
vertexList[v2].visited = true;
DisplayVertex(v2);
theQueue.offer(v2);
}
}
for(int j=0;j<VertexCount;j++) //将访问标记初始化
vertexList[j].visited = false;
}
public int getAdjUnvisitedVertex(int v){ //获得一个未访问的邻接顶点,如果不存在,返回-1
for(int i=0;i<VertexCount;i++)
if(adjMatrix[v][i]==1 && vertexList[i].visited==false)
return i;
return -1;
}
}