图的概念:
邻接、路径、连通图、有向图、带权图
图的存储:
邻接矩阵:二维数组
邻接链表
/*
* 顶点类
*/
public class Vertex {
public char label;
public boolean isVisited;
public Vertex(char label){
this.label=label;
}
}
图的基本操作
/*
* 图类
*/
public class Graph {
//顶点数组
private Vertex[] vertexList;
//邻接矩阵
private int[][] adjMat;
//顶点数目
private int maxSize=20;
//当前顶点
private int nVertex;
public Graph(){
vertexList=new Vertex[maxSize];
adjMat=new int[maxSize][maxSize];
for(int i=0;i<maxSize;i++){
for(int j=0;j<maxSize;j++){
adjMat[i][j]=0;
}
}
nVertex=0;
}
/*
* 添加顶点
*/
public void addVertex(char label){
vertexList[nVertex++]=new Vertex(label);
}
/*
* 添加边
*/
public void addEdge(int start,int end){
adjMat[start][end]=1;
adjMat[end][start]=1;
}
/*
* 获得邻接的未访问过的结点
*/
public int getadjUnvisitedVertex(int v){
for(int i=0;i<nVertex;i++){
if(adjMat[i][v]==1&&vertexList[i].isVisited==false){
return i;
}
}
return -1;
}
public void displayVertex(int v){
System.out.print(vertexList[v].label);
}
}
图的搜索:
1、DFS
步骤:
需要定义一个栈
访问当前顶点一个邻接未访问过的顶点,标记它,放入栈中
如果栈不为空,从栈中弹出一个顶点
直到栈为空
private MyStack stack;
public Graph() {
vertexList = new Vertex[maxSize];
adjMat = new int[maxSize][maxSize];
for (int i = 0; i < maxSize; i++) {
for (int j = 0; j < maxSize; j++) {
adjMat[i][j] = 0;
}
}
nVertex = 0;
stack = new MyStack();
}
public void dfs() {
// 访问0号结点
vertexList[0].isVisited = true;
// 显示该顶点
displayVertex(0);
// 压入栈中
stack.push(0);
while (!stack.isEmpty()) {
// 获得一个未访问过的邻接点
int v = getadjUnvisitedVertex((int) stack.peek());
if (v == -1) {
// 弹出一个顶点
stack.pop();
} else {
vertexList[v].isVisited = true;
displayVertex(v);
stack.push(v);
}
}
// 搜索完后将访问信息修改
for (int i = 0; i < nVertex; i++) {
vertexList[i].isVisited = false;
}
}
2、BFS
步骤:
需要定义一个队列
访问当前顶点所有邻接的未访问过的顶点,标记它,并插入队列中
从队列头取出一个顶点,作为当前顶点
直到队列为空
private MyQueue queue;
public Graph() {
vertexList = new Vertex[maxSize];
adjMat = new int[maxSize][maxSize];
for (int i = 0; i < maxSize; i++) {
for (int j = 0; j < maxSize; j++) {
adjMat[i][j] = 0;
}
}
nVertex = 0;
queue = new MyQueue();
}
public void bfs() {
vertexList[0].isVisited = true;
displayVertex(0);
queue.insert(0);
while (!queue.isEmpty()) {
while (true) {
int v = getadjUnvisitedVertex((int) queue.peek());
if (v == -1) {
queue.remove();
break;
} else {
vertexList[v].isVisited = true;
displayVertex(v);
queue.insert(v);
}
}
}
// 搜索完后将访问信息修改
for (int i = 0; i < nVertex; i++) {
vertexList[i].isVisited = false;
}
}