我在无向图中调试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函数处理这个问题,因此我可以使用人类可理解的矩阵位置。
感谢您的帮助,
答案 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
标准算法是首选,因为它通常应该稍快一些。