我正在尝试用C语言编写深度优先搜索。在搜索中,而不是维护一组所有可到达的节点,而是必须将Vertex中的isVisited字段标记为1。这是我的数据结构和我的算法尝试。
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实施的尝试:
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;
}
此搜索的问题是它永远不会返回节点即使可以访问也是如此。有谁知道我怎么纠正这个?
答案 0 :(得分:1)
在这段代码中
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进度。嗯......甚至可能工作,虽然我不这样做。你确定你的输入是正确的吗?图表是否已连接,即顶点是否可以到达?