作者: 邦_ | 来源:发表于2022-08-05 10:48 被阅读0次

图由顶点(vertex)和边(edge)组成,通常表示为G =(V,E)
任意两个顶点之间都可以用边来表示它们之间的关系,边集合E可以是空的
1、有向图的边是有明确方向的
2、有向无环图(Directed Acyclic Graph)简称DAG
如果一个有向图,从任意顶点出发,无法经过若干条边回到该顶点,那么它就是一个有向无环图
出度(Out-degree)
一个顶点的出度为x,是指有x条边以该顶点为起点
入度(In-degree)
一个顶点的入度为x,是指有x条边以该顶点为终点

无向图(Undirected Graph)
无向图的边是无方向的

混合图(Mixed Graph)
混合图的边可能是无向的,也可能是有向的

平行边
在无向图中,关联一对顶点的无向边如果多于一条,则称这些边为平行边
在有向图中,关联一对顶点的有向边如果多于一条,并且它们的方向相同,则称这些边为平行边

多重图(Multigraph)
有平行边或者有自环的图

简单图(Simple Graph)
既没有平行边也没有自环的图

无向完全图(Undirected Complete Graph)
无向完全图的任意两个顶点之间都存在边
n个顶点的无向完全图有n(n - 1)/2条边

有向完全图 (Directed Complete Graph)
有向完全图的任意两个顶点之间都存在方向相反的两条边
n个顶点的有向完全图有n(n - 1)条边

稠密图(Dense Graph):边数接近于或等于完全图
稀疏图 (Sparse Graph):边数远远小于完全图

有权图(Weighted Graph)
有权图的边可以拥有权值

连通图(Connected Graph)
如果顶点x和y之间存在可相互抵达的路径(直接或间接的路径),则称x和y是连通的

连通分量(Connected Component)
连通分量:无向图的极大连通子图
连通图只有一个连通分量,即其自身
非连通的无向图有多个连通分量

强连通图 (Strongly Connected Graph)
如果有向图中任意两个顶点都是连通的,则称为强连通图

强连通分量(Strongly Connected Component)
强连通分量:无向图的极大连通子图
强连通图只有一个连通分量,即其自身
非连通的无向图有多个强连通分量

import Foundation
import UIKit


class Graph<V: Hashable,E: Hashable>  {
    private var vertices = Dictionary<V,Vertex<V,E>>() //存放顶点
    private var edges = Set<Edge<V, E>>() //存放所有的边
    var edgesSize : Int {
        get {
            
            return edges.count
            
        }
    } //有多少边
    var verticesSize : Int {
        get {
            
            return vertices.count
            
        }
    } //有多少顶点
    
   

    
    //顶点
    class Vertex<V: Hashable,E: Hashable> : Hashable{
        
        var value : V? //顶点上的值
        var inEdges = Set<Edge<V, E>>() //以这个点为终点的边 进来这个点的边
        var outEdges = Set<Edge<V, E>>()//以这个点为起点的边 从这个点出去的边
        func hash(into hasher: inout Hasher) {
            hasher.combine(value)
//            hasher.combine(inEdges)
//            hasher.combine(outEdges)
        }
        
        static func == (lhs: Graph.Vertex<V, E>, rhs: Graph.Vertex<V, E>) -> Bool {
            return lhs === rhs
        }
        
        init(_ v: V){
            
            value = v
        }
        
        
        
        
    }
    
    //边
    class Edge<V: Hashable,E: Hashable> : Hashable{
        
        var form : Vertex<V,E>//起点
        var to : Vertex<V,E>//终点
        var weight :E?//权值
        
        func hash(into hasher: inout Hasher) {
            
            hasher.combine(form)
            hasher.combine(to)
//            hasher.combine(weight)
            
        }
        init(_ form:Vertex<V,E>,_ to:Vertex<V,E>){
            self.form = form
            self.to = to
        }
        
        //起点和终点一样 认为是同一条边
        static func == (lhs: Graph.Edge<V, E>, rhs: Graph.Edge<V, E>) -> Bool {
            
            return (lhs.form == rhs.form) && (lhs.to == rhs.to)
            
        }
        
    }
    
    func printGraph(){
        
        for key in vertices.keys{
            let value:Vertex = vertices[key]!
            print(key,value.value! as Any)
            for edge in value.inEdges {
                print(key,"进来的边",edge.form.value!,edge.to.value!)
            }
            for edge in value.outEdges {
                print(key,"出去的边",edge.form.value!,edge.to.value!)
            }
        }
        
        for value in edges{

            print(value.weight as Any,value.form.value! as Any,value.to.value! as Any)
            
        }
    }
    
    
    //添加顶点
    func addVertex(_ v:V){
        
        if let _ = vertices[v] {
            return
        }
        
        vertices[v] = Vertex<V,E>(v)
        
        
    }
    
    //删除顶点
    func removeVertex(_ v:V){
        guard let tempV = vertices.removeValue(forKey: v) else {
            return
        }
        for e in tempV.outEdges {
            e.to.inEdges.remove(e)
            edges.remove(e)
        }
        for e in tempV.inEdges {
            e.form.outEdges.remove(e)
            edges.remove(e)
        }
        
        
        
        
        
    }
    //添加边
    func addEdge(_ form:V, _ to:V){
        
        addEdge(form, to, nil)
        
        
    }
    //添加边(带权值)
    func addEdge(_ form:V, _ to:V ,_ weight :E?){
        //判断顶点是否存在
        var tempForm : Vertex<V,E>? = nil
        if let temp = vertices[form] {
            tempForm = temp
        }else {
            tempForm = Vertex<V,E>(form)
        }
        
        var tempTo : Vertex<V,E>? = nil
        if let temp = vertices[to] {
            
            tempTo = temp
            
        }else {
            tempTo = Vertex<V,E>(to)
            
        }
        guard let tempForm = tempForm, let tempTo = tempTo else{
            return
        }
     

        
        //创建一个边
        let fe = Edge<V,E>(tempForm,tempTo)
        fe.weight = weight
        if tempForm.outEdges.remove(fe) != nil {
            tempTo.inEdges.remove(fe)
            edges.remove(fe)
        }
        //权值不一样的话 会更新
        tempForm.outEdges.insert(fe)
        tempTo.inEdges.insert(fe)
        edges.insert(fe)
        vertices[form] = tempForm
        vertices[to] = tempTo
        
    }
    //删除边
    func removeEdge(_ form:V, _ to:V){
        
        //判断顶点是否存在
        guard let tempForm = vertices[form], let tempTo = vertices[to] else{
            return
        }
       
        let fe = Edge(tempForm,tempTo)
        if  tempForm.outEdges.remove(fe) != nil {
            
            tempTo.inEdges.remove(fe)
            edges.remove(fe)
            
            
        }

    }
    
    
    
    
    
}

相关文章

网友评论

      本文标题:

      本文链接:https://www.haomeiwen.com/subject/esuxwrtx.html