关于数据结构:c语言中的写入深度优先搜索

writing depth first search in c

我试图在C中编写深度优先搜索。在搜索中,我不需要将所有可访问节点的集合维护,而是将Vertex中的isVisited字段标记为1以便访问。这是我的数据结构和算法尝试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
struct Vertex {
    char label;
    int isVisited;

    int numNeighbors;
    struct Vertex** neighbors;
};
typedef struct Vertex Vertex;

struct Graph {
    int numEdges;
    int numVertices;
    Vertex* vertexSet;
};
typedef struct Graph Graph;

struct DLink {
  TYPE value;
  struct DLink * next;
  struct DLink * prev;

};

struct cirListDeque {
  int size;
  struct DLink *last;
};

typedef struct cirListDeque cirListDeque;

这是我尝试DFS实现的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int DFS(Graph* g, Vertex* source, Vertex* destination) {
    cirListDeque stack;
    TYPE currentVertex;
    int i;

    initCirListDeque(&stack);
    addBackCirListDeque(&stack, source);

    while(!isEmptyCirListDeque(&stack)) {
        currentVertex = backCirListDeque(&stack);
        removeBackCirListDeque(&stack);

        if(currentVertex->label == destination->label) {
            return 1;
        }
        else {
            if(currentVertex->isVisited == 0) {
                currentVertex->isVisited = 1;
                for(i = 0; i < currentVertex->numNeighbors; i++) {
                    if(currentVertex->neighbors[i]->label == destination->label) {
                        return 1;
                    }
                    else {
                        addBackCirListDeque(&stack, currentVertex->neighbors[i]);
                        if(currentVertex->neighbors[i]->isVisited == 0) {
                            addBackCirListDeque(&stack, currentVertex->neighbors[i]);
                        }
                    }
                }
            }
        }
    }

    return 0;
}

此搜索的问题在于,即使它是节点,也永远不会返回该节点可访问的信息。有人知道我该如何纠正?


在这段代码中

1
2
3
4
5
6
                else {
                    addBackCirListDeque(&stack, currentVertex->neighbors[i]);
                    if(currentVertex->neighbors[i]->isVisited == 0) {
                        addBackCirListDeque(&stack, currentVertex->neighbors[i]);
                    }
                }

您出于某种原因将相邻的顶点currentVertex->neighbors[i]添加到DFS堆栈两次。你为什么要做两次?

此外,即使不检查邻居是否已被访问,也可以进行第一次添加。为什么?如果您以这种方式(即在不检查是否已访问过的情况下添加)在循环图中执行此算法,则该算法将陷入一个无尽的循环。它将永远围绕同一周期循环,永远不会到达图形的其他部分。

P.S。在此之前的if(currentVertex->isVisited == 0)检查可能会防止发生无限循环,但是上面的重复加法对我来说是没有意义的。

P.P.S。哦,我想我已经开始了解它了。它被有意地添加了两次:第一个(无条件)添加(用于回溯),第二个(添加检查)以实现向前的DFS进度。嗯...甚至可以用,尽管我不会那样做。您确定输入正确吗?图形是否已连接,即顶点是否真的可以到达?