图的遍历

1.前言

    以图邻接矩阵的存储方式介绍图的深度优先遍历和图的广度优先遍历。
    以下图的图为例简单介绍图的邻接矩阵存储方式。
图
    上图共有9个顶点,15条边,我们用一个二维矩阵来存储顶点之间的连接关系,上图的邻接矩阵如下(0代表两个顶点之间不可达,1代表两个顶点邻接)。

ABCDEFGHI
A110001000
B111000101
C011100001
D001110111
E000111010
F100011100
G010101110
H000110110
I011100001

2.图的深度优先遍历

  1. 从图的某个顶点V出发,访问此顶点,然后从v的未被访问的邻接点出发接着遍历,直至图中所有和V邻接的顶点都被访问到。
  2. 若图中还有节点未访问到,就另选一个未访问的顶点,重复步骤1,直到所有顶点被访问完。

主要代码如下。

//步骤1 i代表顶点下标
void DFS(int i) {
	System.out.print(vertexes[i] + " ");
	visited[i] = true;//访问此顶点
	for(int j = 0; j < numVertexes; j++) {//递归访问其邻接顶点
		if(adjacentMatrix[i][j] == 1 && !visited[j]) {
			DFS(j);
		}
	}
}
//步骤2
void DFSTraverse() {
	//重置所有顶点未访问
	for(int i = 0; i < numVertexes; i++) 
		visited[i] = false;
	System.out.println("深度优先:");
	for(int i = 0; i < numVertexes; i++) {//选一个未访问的顶点,进行步骤1
		if(!visited[i]) {
			DFS(i);
		}
	}
}

3.图的广度优先遍历

  1. 首先访问初始点Vi,并将其标记为已访问过。
  2. 接着访问步骤1中的Vi的所有未被访问过的邻接点Vi1,Vi2,…,,Vit,并均标记已访问过。
  3. 然后再按照Vi1,Vi2,…,,Vit的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。

我们用一个辅助队列存储访问过程中的顶点信息,主要代码如下。

void BFSTraverse() {
	//重置所有顶点未访问
	for(int i = 0; i < numVertexes; i++) 
		visited[i] = false;
	Queue<Integer> Q = new LinkedList<>();//链表实现的辅助队列
	System.out.println("\n广度优先:");
	for(int i = 0; i < numVertexes; i++) {
		if(!visited[i]) {//如果当前顶点未访问
			System.out.print(vertexes[i] + " ");
			visited[i] = true;//访问该顶点
			Q.offer(i);//将该顶点放入辅助队列
			while(!Q.isEmpty()) {
				int temp = Q.poll();//队头弹出队列
				for(int j = 0; j < numVertexes; j++) {//访问队头的邻接顶点
					if(adjacentMatrix[temp][j] == 1 && !visited[j]) {
						System.out.print(vertexes[j] + " ");
						visited[j] = true;//访问邻接顶点
						Q.offer(j);//将访问了的邻接顶点加入辅助队列
					}
				}
			}
		}
	}
}

4.具体实现

    具体的实现代码如下,示例图的测试数据在类的开始的注释。

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/*
--测试数据--
9 15
0 1
0 5
1 2
1 8
1 6
2 3
2 8
3 4
3 7
3 6
3 8
4 5
4 7
5 6
6 7
 */
public class GraphTraverse {
    int numVertexes, numEdges;//顶点数、边数
    char[] vertexes;//顶点集
    int[][] adjacentMatrix;//邻接矩阵
    boolean[] visited;

    //初始化图
    void initGraph() {
        Scanner in = new Scanner(System.in);
        numVertexes = in.nextInt();
        numEdges = in.nextInt();
        vertexes = new char[numVertexes];
        adjacentMatrix = new int[numVertexes][numVertexes];
        visited = new boolean[numVertexes];
        for(int i = 0; i < this.numVertexes; i++) {
            vertexes[i] = (char)(i + 'A');
        }
        for(int i = 0; i < numEdges; i++) {
            adjacentMatrix[in.nextInt()][in.nextInt()] = 1;
        }
        for(int i = 0; i < numVertexes; i++) {
            for(int j = i; j < numVertexes; j++) {
                adjacentMatrix[j][i] = adjacentMatrix[i][j];
            }
        }
        for(int i = 0; i < numVertexes; i++) {
            for(int j = 0; j < numVertexes; j++) {
                System.out.print(adjacentMatrix[i][j] + " ");
            }
            System.out.println();
        }
    }

    void DFS(int i) {
        System.out.print(vertexes[i] + " ");
        visited[i] = true;
        for(int j = 0; j < numVertexes; j++) {
            if(adjacentMatrix[i][j] == 1 && !visited[j]) {
                DFS(j);
            }
        }
    }

    void DFSTraverse() {
        for(int i = 0; i < numVertexes; i++) {
            visited[i] = false;
        }
        System.out.println("深度优先:");
        for(int i = 0; i < numVertexes; i++) {
            if(!visited[i]) {
                DFS(i);
            }
        }
    }

    void BFSTraverse() {
        for(int i = 0; i < numVertexes; i++) {
            visited[i] = false;
        }
        Queue<Integer> Q = new LinkedList<>();
        System.out.println("\n广度优先:");
        for(int i = 0; i < numVertexes; i++) {
            if(!visited[i]) {
                visited[i] = true;
                System.out.print(vertexes[i] + " ");
                Q.offer(i);
                while(!Q.isEmpty()) {
                    int temp = Q.poll();
                    for(int j = 0; j < numVertexes; j++) {
                        if(adjacentMatrix[temp][j] == 1 && !visited[j]) {
                            visited[j] = true;
                            System.out.print(vertexes[j] + " ");
                            Q.offer(j);
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Graph G = new Graph();
        G.initGraph();
        G.DFSTraverse();
        G.BFSTraverse();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值