0

我在无向图中调试 DFS 的实现时遇到问题。

运行过程中,顶点1两次入栈,真不知道为什么会这样。

我在这里附加我的功能:

void dfsFromMatrix(uint64_t **matrix, unsigned vertexes, unsigned root) {
    unsigned *markedItems;
    stack *stackPointer;
    unsigned tempVertex;
    unsigned i;

    markedItems = (unsigned *) calloc(vertexes, sizeof(unsigned));
    stackPointer = NULL;

    stackPointer = stackPush(stackPointer, root);

    while (!checkIfStackIsEmpty(stackPointer)) {
        tempVertex = stackPointer -> data;

#ifdef _DEBUG_
    printf("tempVertex = %u\n", tempVertex);
#endif

        stackPointer = stackPop(stackPointer);
        if (!markedItems[tempVertex]) {
            markedItems[tempVertex] = 1;

#ifdef _DEBUG_
            printf("DFS: Marquei o vértice %u\n", tempVertex);
            printStack(stackPointer);
#endif

            for (i = 1 ; i <= vertexes ; i++)
                if (getValueFromMatrix(matrix, tempVertex, i)) {
                    stackPointer = stackPush(stackPointer, i);
                    printf("Entrei na fila: %u\n", i);
                }

        }
    }   
}

关于 for 循环。它实际上从一个开始并以 <= 顶点结束。getValueFromMatrix 函数处理这个问题,所以我可以使用人类可以理解的矩阵位置。

谢谢你的帮助,

4

1 回答 1

1

取一个带有一个顶点和一个循环边的图。您的算法推送根,标记它,然后继续并推送所有连接到它的顶点,而不检查它们是否被标记。唯一的顶点连接到自身,所以它被第二次推送。

标准 DFS 算法只推送未标记的顶点:

 pop top vertex T
 for all vertex V connected to T
    if V is not marked
      mark V
      push V
      process V

观察标记、推送和处理都是同时完成的。在您的情况下,流程阶段只是打印出顶点,但它可以是任何东西。

您的算法推送连接到未标记顶点的顶点:

 pop top vertex T
 if T is not marked
   mark T
   for all vertex V connected to T          
     push V
     process V

在你的版本标记和推送是分开的。如果您将流程阶段移动到标记阶段旁边,而不是推送阶段旁边,它可能会起作用。

 pop top vertex T
 if T is not marked
   mark T
   process T
   for all vertex V connected to T          
     push V

首选标准算法,因为它通常应该稍快一些。

于 2013-09-21T07:57:18.157 回答