返回

《swift-algorithm-club》——数据结构/图

IOS

图论基础

  • 图的概念

图由一组点(vertices)和连接这些点的边(edges)组成。边可以是无权的或有权的,也可以是有向的或无向的。有向图的边有一个方向,而无向图的边没有方向。

  • 图的表示

图可以用邻接表或邻接矩阵来表示。邻接表是一种将每个点与与之相邻的点存储在列表中的表示方式。邻接矩阵是一种将每个点对之间是否有边存储在矩阵中的表示方式。

  • 图的常见算法

图论中有一些常见的算法,如深度优先搜索、广度优先搜索、最小生成树、最短路径等。这些算法可以用于解决各种问题,如路径寻找、连通性检测、最优路径计算等。

Swift实现

图的表示

struct Vertex<T> {
    let value: T
    var neighbors: [Edge<T>] = []
}

struct Edge<T> {
    let from: Vertex<T>
    let to: Vertex<T>
    let weight: Double
}

图的算法

深度优先搜索

func depthFirstSearch(graph: Graph<T>, start: Vertex<T>) {
    var visited: Set<Vertex<T>> = []
    var stack: Stack<Vertex<T>> = []

    stack.push(start)

    while !stack.isEmpty {
        let current = stack.pop()!

        if !visited.contains(current) {
            visited.insert(current)

            for neighbor in current.neighbors {
                stack.push(neighbor.to)
            }
        }
    }
}

广度优先搜索

func breadthFirstSearch(graph: Graph<T>, start: Vertex<T>) {
    var visited: Set<Vertex<T>> = []
    var queue: Queue<Vertex<T>> = []

    queue.enqueue(start)

    while !queue.isEmpty {
        let current = queue.dequeue()!

        if !visited.contains(current) {
            visited.insert(current)

            for neighbor in current.neighbors {
                queue.enqueue(neighbor.to)
            }
        }
    }
}

最小生成树

func minimumSpanningTree(graph: Graph<T>) -> Graph<T> {
    var visited: Set<Vertex<T>> = []
    var tree: Graph<T> = Graph<T>()

    var edges: [Edge<T>] = graph.edges

    edges.sort { $0.weight < $1.weight }

    for edge in edges {
        if !visited.contains(edge.from) || !visited.contains(edge.to) {
            tree.addEdge(edge.from, to: edge.to, weight: edge.weight)

            if !visited.contains(edge.from) {
                visited.insert(edge.from)
            }

            if !visited.contains(edge.to) {
                visited.insert(edge.to)
            }
        }
    }

    return tree
}

最短路径

func shortestPath(graph: Graph<T>, from: Vertex<T>, to: Vertex<T>) -> [Vertex<T>] {
    var distances: [Vertex<T>: Double] = [:]
    var previous: [Vertex<T>: Vertex<T>] = [:]

    for vertex in graph.vertices {
        distances[vertex] = Double.infinity
        previous[vertex] = nil
    }

    distances[from] = 0

    var queue: PriorityQueue<(Vertex<T>, Double)> = PriorityQueue<(Vertex<T>, Double)>(sort: { $0.1 < $1.1 })

    queue.enqueue((from, 0))

    while !queue.isEmpty {
        let current = queue.dequeue()!.0

        for edge in current.neighbors {
            let neighbor = edge.to
            let weight = edge.weight

            if distances[current]! + weight < distances[neighbor]! {
                distances[neighbor] = distances[current]! + weight
                previous[neighbor] = current

                queue.enqueue((neighbor, distances[neighbor]!))
            }
        }
    }

    var path: [Vertex<T>] = []

    var current: Vertex<T>? = to

    while current != nil {
        path.append(current!)
        current = previous[current!]
    }

    path.reverse()

    return path
}

总结

图论是计算机科学中一个非常重要的领域,有广泛的应用。通过阅读本指南,您对图论有了一个深入的了解,并能使用Swift轻松实现图的算法。