图对建模很有帮助。
图的基本知识:
Java实现图的两种方法
1 邻接矩阵
邻接矩阵是用二维数据,使用1代表节点间有边,如下表格:
| A | B | C | D |
A | 0 | 1 | 1 | 1 |
B | 1 | 0 | 0 | 1 |
C | 1 | 0 | 0 | 0 |
D | 1 | 1 | 0 | 0 |
2 邻接表
临界表是使用类似链表,连接节点,表示有边
定点 | 包含邻接顶点的链表 |
A | B->C->D |
B | A->D |
C | A |
D | A->B |
深度遍历思路:
使用栈,查找栈顶顶点连通到的,没有访问的顶点,使其入栈,并访问。当找不到,则当前栈顶元素出栈。否则继续查找。
广度遍历思路:
使用队列,查找队列头连通的,没有访问的顶点,使其入队列,并访问。当找不到,则当前顶点出队列。否则继续遍历当前队列顶点
他们的不同之处就在,栈访问的顶点变化,会越来越深;队列访问的顶点不变化,只有出队列后才换节点访问。
图在java中的邻接矩阵实现:
package com.Construction;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class GraphSimpleExample {
private final int MAX_VERTS = 20;
private GraphNodeBean nodeList[];
private int adjMat[][];
private int nVerts;
public GraphSimpleExample(){
nodeList = new GraphNodeBean[MAX_VERTS];
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int i = 0; i < MAX_VERTS; i++) {
for (int j = 0; j < MAX_VERTS; j++) {
adjMat[i][j] = 0;
}
}
}
public void addNode(char label){
nodeList[nVerts++] = new GraphNodeBean(label);
}
public void addEdge(int start,int end){
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
public void displayGraphNode(int v){
System.out.println(nodeList[v].label);
}
/**
* 获得未访问节点
* @param v
* @return
*/
public int getAdjUnvisitedVertex(int v){
for (int i = 0; i < nVerts; i++) {
if(adjMat[v][i]==1 && nodeList[i].isVisited == false)
return i;
}
return -1;
}
/**
* deft first
*/
public void dfs(){
@SuppressWarnings("rawtypes")
Stack<Integer> theStack = new Stack<Integer>();
nodeList[0].isVisited = true;
displayGraphNode(0);
theStack.push(0);
while(!theStack.isEmpty()){
int v = getAdjUnvisitedVertex(theStack.peek());
if(v == -1)
theStack.pop();
else{
nodeList[v].isVisited = true;
displayGraphNode(v);
theStack.push(v);
}
}
// for (int i = 0; i < nVerts; i++) {
// nodeList[i].isVisited = false;
// }
}
public void bds(){
Queue<Integer> theQueue = new LinkedList<Integer>();
nodeList[0].isVisited = true;
displayGraphNode(0);
theQueue.offer(0);
int v2;
while(!theQueue.isEmpty()){
int v1 = theQueue.poll();
while((v2 = getAdjUnvisitedVertex(v1)) != -1){
nodeList[v2].isVisited = true;
displayGraphNode(v2);
theQueue.add(v2);
}
}
// for (int i = 0; i < nVerts; i++) {
// nodeList[i].isVisited = false;
// }
}
}
其中dfs是深度优先算法
bfs是广度优先算法