• 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 }
  • 相关阅读:
    利用GetInvalidFileNameChars()得到有效的文件名
    C# 下载远程http文件到本地
    CLR无法从COM 上下文*****转换为COM上下文*****,这种状态已持续60秒。
    Wpf UserControl使用 KeyBinding,失效问题
    C# windows服务知识集锦
    制作Windows服务和安装程序(C#版)
    C语言内存管理
    Python初学注意问题
    msp430学习笔记-USART
    msp430学习笔记-ADC12
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/12871412.html
Copyright © 2020-2023  润新知