数据结构 -- 无向图 环检测

环的定义

在无向图中出现回路,环不包含自环和平行边
数据结构 -- 无向图 环检测_第1张图片


图中环检测 scala 实现

CycleDetection.scala


import util.control.Breaks.{
     break, _}

class CycleDetection {
     
  var G: Graph = _
  var visited: Array[Boolean] = _
  var hasCycle = false

  def this(g: Graph) = {
     
    this()
    this.G = g
    visited = Array.ofDim[Boolean](g.getV())
    for (i <- 0 until g.getV()) {
     
      visited(i) = false
    }
    //var stop = false

    breakable(
      for (i <- 0 until g.getV()) {
     
        if (!visited(i) && dfs(i, i)) {
     
            hasCycle = true
            break()
        }
      }
    )

  }

  def haveCycle(): Boolean = {
     
    hasCycle
  }

  def dfs(v: Int, parent: Int): Boolean = {
     
    visited(v) = true
    var result = false

    breakable(
      for (w <- G.getAdjacentSide(v)) {
     
        if (!visited(w)) {
     
          if (dfs(w, v)) {
     
            result = true
            break()
          }
        } else if (w != parent) {
     
          result = true
          break()
        }
      }
    )

    result
  }
}

object CycleDetection {
     
  def apply(g: Graph): CycleDetection = new CycleDetection(g)

  def main(args: Array[String]): Unit = {
     
    val graph = Graph().createGraph("./data/graph/g.txt")
    val connectedComponents = CycleDetection(graph)
    println(connectedComponents.haveCycle())

    val graph2 = Graph().createGraph("./data/graph/g2.txt")
    val connectedComponents2 = CycleDetection(graph2)
    println(connectedComponents2.haveCycle())
  }
}

// true
// false

图 Graph.scala

import java.io.File
import java.util.Scanner

import scala.collection.mutable.{
     ArrayBuffer, TreeSet}

class Graph {
     
  var V = 0 // 顶点
  var E = 0 // 边
  var adj: Array[TreeSet[Int]] = _ // 红黑树数组

  def createGraph(filename: String): Graph = {
     
    val scanner = new Scanner(new File(filename))
    V = scanner.nextInt()
    adj = Array.ofDim[TreeSet[Int]](V)
    for (i <- 0 until V) {
     
      adj(i) = TreeSet.empty
    }
    E = scanner.nextInt()
    for (i <- 0 until E) {
     
      val a = scanner.nextInt()
      val b = scanner.nextInt()
      //println(s"$a + $b")
      var as = adj(a)
      //if (as == null) as = TreeSet.empty
      as.add(b)
      adj(a) = as
      var bs = adj(b)
      //if (bs == null) bs = TreeSet.empty
      bs.add(a)
      adj(b) = bs
    }
    this
  }

  override def toString: String = {
     
    val sb = new StringBuffer()
    for (i <- 0 until adj.length) {
     
      sb.append(s"顶点 $i ->\t")
      if (adj(i) != null) {
     
        for (y <- adj(i)) {
     
          sb.append(s"$y\t")
        }
      }
      sb.append("\n")
    }
    sb.toString
  }

  /**
   * 获得 图中顶点的个数
   *
   * @return
   */
  def getV() = {
     
    V
  }

  /**
   * 获得 图中边的个数
   *
   * @return
   */
  def getE() = {
     
    E
  }


  /**
   * 两个顶点间是否有边
   *
   * @param v
   * @param w
   * @return
   */
  def hasEdge(v: Int, w: Int) = {
     
    adj(v).contains(w)
  }

  /**
   * 获取v的所有邻边
   *
   * @param v
   * @return
   */
  def getAdjacentSide(v: Int) = {
     
    if (adj(v) != null) {
     
      adj(v).toList
    } else {
     
      Nil
    }
  }
}

object Graph {
     
  def main(args: Array[String]): Unit = {
     
    val graph = Graph()
    graph.createGraph("./data/graph/g.txt")
    println(graph)

    println("-------------------------")
    println(s"顶点个数:${graph.getV()}")
    println("-------------------------")
    println(s"边的个数:${graph.getE()}")
    println("-------------------------")
    println(s"2的邻边:${graph.getAdjacentSide(2)}")
    println("-------------------------")
    println(s"1 和 2 是否有边:${graph.hasEdge(1, 2)}")
  }

  def apply(): Graph = new Graph()
}


g.txt

7 6
0 1
0 2
1 3
1 4
2 3
2 6

g2.txt

7 5
0 1
0 2
1 3
1 4
2 6

你可能感兴趣的:(scala,数据结构,无向图,环检测)