【发布时间】:2018-02-03 01:11:08
【问题描述】:
我正在尝试使用自制数据结构(HashMap 和 LinkedList)在有向图上实现一个简单的 DFS 来学习 C++,但由于某种原因,DFS 方法无限重复。
我认为它是无限循环的,因为由于某种原因,存储在哈希图(图表)中的节点实际上并未在 DFS 期间被标记为已访问。我以为我理解指针和引用,但显然我不理解。如果有人能帮我看看我做错了什么,我将不胜感激。
这是无限循环的 DFS 方法:
template <class T>
bool Graph<T>::DFS(const T& v1, const T& v2) {
if(v1 == v2)
return true;
Graph<T>::Node * node = *(map->find(v1));
node->visited = true;
for(int i = 0; i < node->adjacent->size(); i++)
if(node->adjacent->get(i).visited == false)
return DFS(node->adjacent->get(i).data, v2);
return false;
}
这里是 HashMap 类的 find() 方法
template <class K, class V>
V* HashMap<K, V>::find(const K& key) const {
int bucket = (int) hash_fn(key) % arrLength;
HashMap<K, V>::Node * temp = buckets[bucket];
while(temp != NULL && temp->key != key)
temp = temp->next;
if(temp == NULL)
return NULL;
else
return &(temp->value);
}
这是 Graph 类
template <class T>
class Graph {
struct Node {
T data;
bool visited;
LinkedList<Node> * adjacent;
Node() {
adjacent = nullptr;
visited = false;
}
Node(T data) {
this->data = data;
adjacent = new LinkedList<Node>();
visited = false;
}
};
public:
Graph();
~Graph();
void addEdge(const T& v1, const T& v2);
bool DFS(const T& v1, const T& v2);
private:
HashMap<T, Graph<T>::Node*> * map;
};
template <class T>
Graph<T>::Graph() {
map = new HashMap<T, Graph<T>::Node*>();
}
template <class T>
Graph<T>::~Graph() {
map->~Map<T, Graph<T>::Node*>();
}
template <class T> // directed graph
void Graph<T>::addEdge(const T& v1, const T& v2) { // add edge from v1 to v2
if(map->find(v1) == NULL)
map->insert(v1, new Graph<T>::Node(v1));
if(map->find(v2) == NULL)
map->insert(v2, new Graph<T>::Node(v2));
(*map->find(v1))->adjacent->append( **map->find(v2) ); // oh god
}
这是我构造和填充图形的 Main 方法,然后调用 DFS 方法。
int main() {
Graph<int> * graph1 = new Graph<int>();
graph1->addEdge(1, 5);
graph1->addEdge(5, 9);
graph1->addEdge(9, 20);
graph1->DFS(1, 20);
return 0;
}
在此先感谢您提供任何帮助或见解。 -鲍勃
【问题讨论】:
-
HashMap<T, Graph<T>::Node*>这对我来说看起来很奇怪,你最好使用HashMap<T, Graph<T>::Node>并让 HashMap 在有意义的地方添加指针限定符。 -
also:
map->~Map<T, Graph<T>::Node*>();这看起来像是纯粹的邪恶,而且肯定会发生内存泄漏。有什么理由不打电话给delete map;? -
更多与您的实际问题相关:
LinkedList<Node>我不知道该模板是如何实现的,但如果它类似于标准容器,这将在每个边引用内创建图形副本引用节点,导致一个巨大的 DAG,如果你在一段时间后暂停执行,它可能看起来无限大。这是LinkedList<Node*>更有意义的情况。 -
@Frank 谢谢,我将
LinkedList<Node>更改为LinkedList<Node*>并修复了它。但老实说,我不明白为什么要修复它。 -
@Frank 我不想只调用
delete map,因为我认为我需要调用析构函数来删除邻接列表中的所有节点。
标签: c++ pointers reference pass-by-reference depth-first-search