深度优先遍历
深度优先遍历是从初始顶点出发,初始顶点可能存在有个邻接顶点,深度优先遍历的策略就是首先访问第一个邻接顶点,然后再以这个被访问的邻接顶点作为初始顶点访问它的第一个邻接顶点。
深度优先遍历的步骤
(1) 访问顶点v,并将访问点v标记成已访问。 (2) 依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问。 (3) 若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 ↑↑↑(上面这个wx公众号) 数据结构与算法可视化演示
代码
public class Graph {
private ArrayList<String> vertexList;
private int[][] edges;
private int numOfEdges;
private boolean[] isVisited;
public static void main(String[] args) {
String[] vertexs = {"A","B","C","D","E"};
Graph graph = new Graph(vertexs.length);
for (String vertex:vertexs) {
graph.insertVertex(vertex);
}
graph.insertEdges(0,1,1);
graph.insertEdges(0,2,1);
graph.insertEdges(1,2,1);
graph.insertEdges(1,3,1);
graph.insertEdges(1,4,1);
System.out.println("深度优先遍历");
graph.dfs();
}
public Graph(int n){
edges = new int[n][n];
vertexList = new ArrayList<>(n);
isVisited = new boolean[n];
numOfEdges = 0;
}
public int getFirstNeighbor(int index){
for (int i = 0; i < vertexList.size(); i++) {
if (edges[index][i] > 0){
return i;
}
}
return -1;
}
public int getNextNeighbor(int v1,int v2){
for (int j = v2+1; j < vertexList.size(); j++) {
if (edges[v1][j] > 0){
return j;
}
}
return -1;
}
public void dfs(boolean[] isVisited,int i){
System.out.print(getValueByIndex(i)+"->");
isVisited[i] = true;
int neighbor = getFirstNeighbor(i);
while(neighbor != -1){
if (!isVisited[neighbor]){
dfs(isVisited,neighbor);
}
neighbor = getNextNeighbor(i,neighbor);
}
}
public void dfs(){
for (int i = 0; i < getNumOfVertex(); i++) {
if (!isVisited[i]){
dfs(isVisited,i);
}
}
}
public void insertVertex(String vertex){
vertexList.add(vertex);
}
public void insertEdges(int v1,int v2,int weight){
edges[v1][v2] = weight;
edges[v2][v1] = weight;
numOfEdges++;
}
public int getNumOfVertex(){
return vertexList.size();
}
public String getValueByIndex(int index){
return vertexList.get(index);
}
}
运行结果
深度优先遍历
A->B->C->D->E
Process finished with exit cod
广度优先遍历
图的广度优先遍历类似于树的层序遍历,广度优先遍历需要用一个队列以保持访问过的顶点的顺序,以便按照这个顺序来访问这些顶点的邻接顶点。
广度优先遍历的步骤
(1)访问初始顶点v并标记顶点v已经被访问。 (2)将顶点v入队。 (3)当队列不为空时取出队列的头结点u,队列为空则结束算法。 (4)查找头结点u的未被访问的邻接顶点。 (5)将未被访问的邻接顶点入队并标记已访问。 (6)跳转到步骤3直到图中所有顶点均被访问过为止。
代码
public void bfs(boolean[] isVisited,int i){
int u;
int neighbor;
LinkedList queue = new LinkedList();
System.out.print(getValueByIndex(i)+"->");
isVisited[i] = true;
queue.addLast(i);
while(!queue.isEmpty()){
u =(Integer) queue.removeFirst();
neighbor = getFirstNeighbor(u);
while(neighbor != -1){
if(!isVisited[neighbor]){
System.out.print(getValueByIndex(neighbor)+"->");
isVisited[neighbor] = true;
queue.addLast(neighbor);
}
neighbor = getNextNeighbor(u,neighbor);
}
}
}
public void bfs(){
for (int i = 0; i < getNumOfVertex(); i++) {
if (!isVisited[i]){
bfs(isVisited,i);
}
}
}
public static void main(String[] args) {
String[] vertexs = {"A","B","C","D","E"};
Graph graph = new Graph(vertexs.length);
for (String vertex:vertexs) {
graph.insertVertex(vertex);
}
graph.insertEdges(0,1,1);
graph.insertEdges(0,2,1);
graph.insertEdges(1,2,1);
graph.insertEdges(1,3,1);
graph.insertEdges(1,4,1);
System.out.println("广度优先遍历");
graph.bfs();
}
运行结果
广度优先遍历
A->B->C->D->E
Process finished with exit code 0
|