顶点在DFS堆栈中输入两次

时间:2013-09-21 06:15:43

标签: c graph stack

我在无向图中调试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循环。它实际上从一开始,以&lt; =顶点结束。 getValueFromMatrix函数处理这个问题,因此我可以使用人类可理解的矩阵位置。

感谢您的帮助,

1 个答案:

答案 0 :(得分: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

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