这个dijkstra算法的时间复杂度?

时间:2020-03-31 12:47:06

标签: python time-complexity dijkstra

看到优先级队列可以和| E |一样大,此Dijkstra代码的时间复杂度是多少? (可能会将节点添加到优先级队列中的时间不止一次)。我想推断出while循环内的时间复杂度。

def shortestReach(n, edges, start,target):

    adjList = collections.defaultdict(list)

    for parent, child, cost in edges:
        parent -= 1
        child -= 1
        adjList[parent].append((child, cost))
        adjList[child].append((parent, cost))

    priorityQueue = queue.PriorityQueue()
    priorityQueue.put((0, start))
    visited = set()
    while priorityQueue.qsize() > 0:
        costPar, parent = priorityQueue.get()

        if parent == target:
            return costPar

        if parent in visited:
            continue

        for adj in adjList[parent]:
            child, cost = adj
            if child not in visited:
                priorityQueue.put((cost + costPar, child))

        visited.add(parent)

我的想法:由于priorityQueue可以和| E |一样大,因此下面的行最多可以出现| E |。次数,但从队列中取出的节点将不会得到处理,因为我们进行了访问集检查。因此是| E | log | E |

costPar, parent = priorityQueue.get()

下面的for循环最多可以运行| E |。因为每个节点仅由于访问集而被处理一次,所以推理是它最多可以占用| E | log | E |。最多次数

for adj in adjList[parent]:
            child, cost = adj
            if child not in visited:
                priorityQueue.put((cost + costPar, child))

总体时间复杂度为2 * | E | log | E | -> O(| E | log | E |)?

1 个答案:

答案 0 :(得分:1)

内部循环对于每个顶点最多执行一次。它的迭代总数是每个顶点的度数之和,等于边数的两倍。结果,它最多执行2*E次。

priorityQueue.put((cost + costPar, child))行在堆中插入一个节点,这是一个O(log(size_of_heap))操作。请注意,size_of_heap<=E

结合以上内容,我们得到O(|E| * log |E|)