目录
一、图
图通常用一个二元组G=<V,E>表示,V表示节点集,E表示边集。|V|表示节点集中元素的个数,即节点数,|E|表示边集中元素的个数。如果图中每条边都是没有方向的,称为无向图,如果图中每条边都有方向,则称为有向图。图的常见实现分为:邻接矩阵和邻接表。
二、实现
邻接矩阵
package Algorithm.graph
/*
* 邻接矩阵
*/
public class GraphAdjMatrix {
private var adjMatrix: Array<Array<Int64>>
private var numVertices: Int64
public init(numVertices: Int64) {
this.numVertices = numVertices
this.adjMatrix = Array<Array<Int64>>(numVertices, item: Array<Int64>(numVertices, item: 0))
}
// 添加边
public func addEdge(i: Int64, j: Int64): Unit {
// 无向图需要对称设置
adjMatrix[i][j] = 1
adjMatrix[j][i] = 1
}
// 移除边
public func removeEdge(i: Int64, j: Int64): Unit {
// 无向图需要对称设置
adjMatrix[i][j] = 0
adjMatrix[j][i] = 0
}
// 打印邻接矩阵
public func printMatrix(): Unit {
for (i in 0..numVertices) {
for (j in 0..numVertices) {
print("${adjMatrix[i][j]} ")
}
println()
}
}
// 检查两个顶点之间是否有边
public func hasEdge(i: Int64, j: Int64): Bool {
return adjMatrix[i][j] == 1
}
}
邻接表
package Algorithm.graph
import std.collection.*
/*
* 节点
*/
class Node{
//起始点下标
public var src: Int64
//终止点下标
public var dest: Int64
//权值
public var weight: Int64
public var next: Option<Node> = Option<Node>.None
public Node(src: Int64, dest: Int64, weight: Int64) {
this.src = src
this.dest = dest
this.weight = weight
}
}
/*
* 邻接表
*/
public class GraphAdjList {
//顶点集
private var arrayV: Array<String>
//是否是有向图
private var isDirect: Bool
//存储顶点下标
private var indexV: HashMap<String, Int64> = HashMap<String, Int64>()
//存储每个顶点的边结点链表
private var list: ArrayList<Node>
public init (size: Int64, isDirect: Bool){
this.arrayV = Array<String>(size, item: "")
this.isDirect = isDirect
//给个初始大小并且置为null,方便后面判断
this.list = ArrayList<Node>(size)
}
/**
* 初始化顶点集
*/
public func initArrayV(arrV: Array<String>): Unit {
for (i in 0..arrV.size) {
this.arrayV[i] = arrV[i]
this.indexV.put(arrV[i], i)
}
}
/**
* 插入边结点到链表中
*/
public func addEdge(v1: String, v2: String, weight: Int64){
let src = indexV[v1]
let dest = indexV[v2]
addEdgeChild(src, dest, weight)
//如果是无向图,需要反着再添加一次
if(!isDirect){
addEdgeChild(dest, src, weight)
}
}
private func addEdgeChild(src: Int64, dest: Int64, weight: Int64): Unit {
let node = Node(src, dest, weight)
//头插入法
//获取src的链表头位置
let cur= list.get(src)
if(cur.isNone()){
list.set(src, node)
} else {
let tmp = list.get(src)
node.next = tmp
list.set(src, node)
}
}
public func printGraph(): Unit {
for (i in 0..arrayV.size) {
print("${arrayV[i]}-> ")
var cur = list.get(i)
while (cur.isSome()) {
match (cur) {
case Some(c) =>
print("${c.dest}-> ")
cur = c.next
case None => return
}
}
println("空")
}
}
}
三、小结
本章为大家详细的介绍了仓颉数据结构与算法中图的内容,下一章,为大家带来图的遍历。最后,创作不易,如果大家觉得我的文章对学习仓颉数据结构与算法有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!