图
图是一种复杂的非线性结构。图G由两个集合V(顶点Vertex)和E(边Edge)组成,定义为G=(V,E)
底层存储结构
存储结构有两种方式:
链表存储:如上图
二叉树存储:hash表、红黑树实现(如下图),hash表查询效率比红黑树略高,但需要更大的空间
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)
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()
}
顶点 0 -> 1 3
顶点 1 -> 0 2 6
顶点 2 -> 1 3 5
顶点 3 -> 0 2 4
顶点 4 -> 3 5
顶点 5 -> 2 4 6
顶点 6 -> 1 5
-------------------------
顶点个数:7
-------------------------
边的个数:9
-------------------------
2的邻边:List(1, 3, 5)
-------------------------
1 和 2 是否有边:true
文件 g.txt
7 9
0 1
0 3
1 2
1 6
2 3
2 5
3 4
4 5
5 6