【问题标题】:Finding the diameter of m-ary tree - C查找 m-ary 树的直径 - C
【发布时间】:2019-11-24 16:35:17
【问题描述】:

我必须在 C 中分析一个 m-ary 树 - 使用 BFS。

有一些要求我暂时没有成功实现:

1.求树的直径。

2。给定树中的两个顶点 - 找到它们之间的最短简单路径。

至于 1 - 我浏览了 Stack 中的主题 - 并且看到了一些对我来说不是很清楚的实现(不幸的是不是在 C 中)......通过使用 BFS 两次来计算直径的某种方法,从随机顶点... 我不确定第二个 BFS 是否必须“记住”第一个 BFS 中访问过的数组

至于 2 - 我真的不知道该怎么做,但我相信我可以在这里使用 BFS

  • 而且,我必须以 O(n^2) 的时间复杂度来实现这两个要求。

  • 除此之外,我还必须找到树的最大和最小高度。

  • 至于最大高度 - 我已经实施了 BFS(不确定它是否绝对正确)据我了解,它处理这个最大高度

  • 至于最小高度 - 我不知道如何找到它

这是我的顶点结构和 BFS 实现:

typedef struct Vertex {
    size_t key;
    size_t amountOfNeighbors; // The current amount of neighbors
    size_t capacity; // The capacity of the neighbors (It's updating during run-time)
    struct Vertex* parent;

    struct Vertex** neighbors; // The possible parent and children of a vertex
} Vertex;

Vertex* bfs(Vertex* allVertices, size_t numOfVertices, Vertex* startVertex, size_t* pathDistance) {

    if (startVertex -> neighbors == NULL) { // In case we have only one vertex in the graph
        *pathDistance = 0;
        return startVertex;
    }

    Queue* q = (Queue*)malloc((sizeof(size_t) * numOfVertices));
    int* visited = (int*)malloc(sizeof(int) * numOfVertices);
    for (size_t i = 0; i < numOfVertices; i++) {
        visited[i] = 0; // Mark all the vertices as unvisited
    }

    size_t lastVertex = 0; // Actually indicates the furthermost vertex from startVertex
    *pathDistance = 0; // The number of edges between lastVertex and startVertex

    enqueue(q, startVertex->key);
    visited[startVertex->key] = 1; // Mark as visited

    while (!queueIsEmpty(q)) {
        unsigned int currentVertex = dequeue(q); // The key of the current vertex
        Vertex* s = &allVertices[currentVertex];

        size_t currentAmountOfNeighbors = 0; // Detects the number of processed neighbors of the current vertex
        for (Vertex **child = s->neighbors; currentAmountOfNeighbors < s->amountOfNeighbors; currentAmountOfNeighbors++) {
            if (!visited[(*(child))->key]) {
                visited[(*(child))->key] = 1;
                enqueue(q, (*(child))->key);
                child++; // TODO Validate it's a correct use of memory!
            }
        }
        *pathDistance += 1; // Another layer passed
        lastVertex = peekQueue(q);
    }

    Vertex* furtherMostVertexFromS = &allVertices[lastVertex];
    free(q);
    q = NULL;
    return  furtherMostVertexFromS;
}

我的困难和疑惑以粗体显示,我们将不胜感激。

【问题讨论】:

    标签: c pointers path height breadth-first-search


    【解决方案1】:

    首先,这种性质的问题更适合CS Stack Exchange,但无论如何我都会尽力提供帮助

    对于您的第一个问题(查找直径),请注意树的最长路径必须以树中最深的节点(即叶子)开始(或结束)。 BFS 帮助你找到所有节点的深度,从而帮助你找到最深的节点。你能从那里弄清楚如何找到所说路径的尽头吗?提示:想想寻找图中最深节点的过程。

    您似乎对 BFS 的工作方式存在误解:请注意,跟踪访问过的节点的目的是避免穿过后边缘 - 即避免循环 - 这在一颗树。 但是假设,即使您确实维护了这样一个“已访问”数组(例如,如果您希望您的算法处理循环图),为什么它会在不同的 BFS 调用之间共享?

    至于第二个问题:BFS 求图中节点与起始节点之间的距离(从根调用时也称为“深度”)。特别是,这些是最短路径(在未加权图上)

    其余粗体问题的答案也是相关的,关键是在无环、未加权的图中 - BFS 可让您找到距起始节点的最短路径/最小距离(有关更多详细信息,请参阅算法教科书在那)

    【讨论】:

    • Re "您似乎对 BFS 的工作方式存在误解:请注意,跟踪访问节点的目的是避免穿过后边缘 “,是的,不是的。 OP 试图找到树中两个节点之间的最短路径,这需要构建访问节点列表(潜在路径)。这就是在之前与 OP 的讨论中记住访问过的节点的意思
    • @NMDanny 至于直径 - 如果我理解你的话 - 我唯一要做的就是找到直径,实际上是多次调用 BFS 函数?每个调用都包含作为 startVertex - 根的另一个孩子?直径是两个最大深度的总和?.. 至于访问问题 - 我从您的解释中了解到我在函数中访问的数组就足够了。至于第二个问题 - 现在我真的很困惑。 BFS 如何准确找到最短路径?而且它只需要一个顶点 - 那么在这种情况下你所说的路径是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    相关资源
    最近更新 更多