Java邻接矩阵存储图简易版以及深度优先优先遍历和广度优先遍历

数据结构课上学的邻接表存储图只能用来学习使用,真正写算法题的是否如果也写那么多个类,构建图和DFS操作这么多还这么复杂,那肯定时间不够,所以下面介绍一种刷题的时候比较实用的一种方式,一般不需要创建类,或者最多只需创建一个类

如果每个边没有权重,使用ArrayList<LinkedList<Integer> G来存储图
 1 public class Solution1 {
 2     // 邻接表存储图
 3     public static final int MAXV = 1000;
 4     public static boolean[] vis = new boolean[MAXV];
 5     public static int n;
 6     //
 7     public static ArrayList<LinkedList<Integer>> G = new ArrayList<>(MAXV);  // 存储图的邻接表
 8 
 9     public static void main(String[] args) {
10         Scanner in = new Scanner(System.in);
11         // 读取一个图的数据
12         n = in.nextInt();
13         int e = in.nextInt();
14 
15         // 读取所有边的数据
16         for(int i = 0; i < e; i++){
17             int u = in.nextInt();
18             int v = in.nextInt();
19             G.get(u).add(v);
20             G.get(v).add(u);
21         }
22 
23         // DFS遍历图
24         DFSTrave();
25 
26     }
27 }

深度优先遍历

 1 public static void DFSTrave(){
 2     for(int u = 0; u < n; u++){
 3         if(vis[u] == false){
 4             DFS(u, 1);
 5         }
 6     }
 7 }
 8 
 9 // 从u顶点开始遍历该连通分量
10 private static void DFS(int u, int depth) {
11     vis[u] = true;      // 设置u已被访问
12     // 遍历u的所有邻接点
13     for(int i = 0; i < G.get(u).size(); i++){
14         int v = G.get(u).get(i);
15         if(vis[v] == false){        // 如果这个邻接点没有访问过,DFS访问它
16             DFS(v, depth + 1);
17         }
18     }
19 }

广度优先遍历

 1 public static boolean[] inq  = new boolean[MAXV];
 2 private static void BFS(int u) {
 3     // 初始化inq数组
 4     Arrays.fill(inq, false);
 5     Queue<Integer> queue = new LinkedList<Integer>();
 6     // 入队u
 7     queue.offer(u);
 8     // 标记u已入队
 9     inq[u] = true;
10 
11     // 循环
12     while(!queue.isEmpty()){
13         // 出队队首元素
14         Integer top = queue.poll();
15 
16         // 所有未入队邻接点入队
17         for(int i = 0; i < G.get(top).size(); i++){
18             int v = G.get(top).get(i);
19             if(inq[v] == false){
20                 queue.offer(v);
21                 inq[v] = true;
22             }
23         }
24 
25     }
26 }

如果边有权重,需要创建一个类来表示AdjV邻接点, 使用ArrayList<LinkedList<AdjV>> G来存储图
 1 public class Solution2 {
 2     // 邻接表存储图
 3     public static final int MAXV = 1000;
 4     public static boolean[] vis = new boolean[MAXV];
 5     public static int n;
 6     
 7     public static class AdjV{
 8         public int v;         // 邻接点
 9         public int weight;  // 边的权重
10         public AdjV(int v, int weight){
11             this.v = v;
12             this.weight = weight;
13         }
14     }
15     
16     public static ArrayList<LinkedList<AdjV>> G = new ArrayList<>(MAXV);  // 存储图的邻接表
17 
18     public static void main(String[] args) {
19         Scanner in = new Scanner(System.in);
20         // 读取一个图的数据
21         n = in.nextInt();
22         int e = in.nextInt();
23 
24         // 读取所有边的数据
25         for(int i = 0; i < e; i++){
26             int u = in.nextInt();
27             int v = in.nextInt();
28             int weight = in.nextInt();
29             G.get(u).add(new AdjV(v, weight));
30             G.get(v).add(new AdjV(u, weight));
31         }
32 
33         // DFS遍历图
34         DFSTrave();
35 
36     }
37 }

对应的深度优先遍历

 1 public static void DFSTrave(){
 2     for(int u = 0; u < n; u++){
 3         if(vis[u] == false){
 4             DFS(u, 1);
 5         }
 6     }
 7 }
 8 
 9 // 从u顶点开始遍历该连通分量
10 private static void DFS(int u, int depth) {
11     vis[u] = true;      // 设置u已被访问
12     // 遍历u的所有邻接点
13     for(int i = 0; i < G.get(u).size(); i++){
14         AdjV adjV = G.get(u).get(i);
15         if(vis[adjV.v] == false){        // 如果这个邻接点没有访问过,DFS访问它
16             DFS(adjV.v, depth + 1);
17         }
18     }
19 }

广度优先遍历,

 1 public static void DFSTrave(){
 2     for(int u = 0; u < n; u++){
 3         if(vis[u] == false){
 4             BFS(u);     // 遍历u所在的连通块
 5         }
 6     }
 7 }
 8 
 9 public static boolean[] inq  = new boolean[MAXV];
10 private static void BFS(int u) {
11     // 初始化inq数组
12     Arrays.fill(inq, false);
13     Queue<Integer> queue = new LinkedList<>();
14     // 入队u
15     queue.offer(u);
16     // 标记u已入队
17     inq[u] = true;
18 
19     // 循环
20     while(!queue.isEmpty()){
21         // 出队队首元素
22         Integer top = queue.poll();
23 
24         // 所有未入队邻接点入队
25         for(int i = 0; i < G.get(top).size(); i++){
26             AdjV adjV = G.get(top).get(i);
27             if(inq[adjV.v] == false){
28                 queue.offer(adjV.v);
29                 inq[adjV.v] = true;
30             }
31         }
32 
33     }
34 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值