使用指针和引用,无法弄清楚为什么DFS无限重复
Using pointers and references, can't figure out why DFS is recurring infinitely
我正在尝试使用自制的数据结构(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);
}
下面是图形类
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*>
,而缺乏应该有的指针:LinkedList<Node> * adjacent
。
您还可以在毫无意义的地方使用动态分配,例如Node
的 afformentionadjacent
成员,并且您的清理要么不存在(Graph::Node
没有析构函数,而它应该有一个析构函数(,要么完全损坏(Graph<T>::~Graph()
将导致有保证的内存泄漏(。
此外,没有任何内容可以清理你的visited
标志,因此只需调用DFS即可。
坦率地说,你的代码在设计和实现方面都存在很多问题。
您的特定 DFS 问题可能来自对LinkedList<Node>
而不是LinkedList<Node*>
用于 adjency 列表,因为这可能会导致图形成为一个巨大的 DAG,其中子图形复制到 adjency 列表中,但如果不知道如何实现LinkedList<>
,就很难判断。
编辑我只是直言不讳地说"这很糟糕",感觉有点糟糕,这是我正确实现代码的方法(使用 stl 而不是自定义容器(:
#include <unordered_map>
#include <vector>
template<typename T>
class Graph {
struct Node {
T data;
bool visited;
std::vector<Node*> adjacent;
Node(T const& d) : data(d), visited(false) {}
};
public:
inline void addEdge(T const& v1, T const& v2);
inline bool DFS(T const& v1, T const& v2);
private:
inline bool DFS_recur(T const& v1, T const& v2);
std::unordered_map<T, Node> map;
};
template<typename T>
void Graph<T>::addEdge(T const& v1, T const& v2) {
auto v1_found = map.emplace(v1, v1).first;
auto v2_found = map.emplace(v2, v2).first;
v1_found->second.adjacent.emplace_back(&v2_found->second);
}
template<typename T>
bool Graph<T>::DFS(T const& v1, T const& v2) {
auto result = DFS_recur(v1, v2);
// Return to the invariant state.
for(auto & n : map) {
n.second.visited = false;
}
return result;
}
template<typename T>
bool Graph<T>::DFS_recur(T const& v1, T const& v2) {
if(v1 == v2) return true;
auto v1_found = map.find(v1);
// If v1 is not in the map, we'll be in trouble.
if(v1_found == map.end()) return false;
v1_found->second.visited = true;
for(auto const & neighbour : v1_found->second.adjacent) {
if(!neighbour->visited) {
return DFS_recur(neighbour->data, v2);
}
}
return false;
}
int main() {
Graph<int> graph1;
graph1.addEdge(1, 5);
graph1.addEdge(5, 9);
graph1.addEdge(9, 20);
graph1.DFS(1, 20);
return 0;
}
请注意所有内存管理是如何通过 RAII 处理的,而不是new
或delete
。
- N-queen问题:无法弄清楚为什么我的解决方案不起作用
- 为什么我的编译器无法弄清楚这种转换,它何时存在?
- 循环不继续无法弄清楚为什么
- 无法弄清楚为什么没有调用重载运算符 []
- 谁能弄清楚为什么我的循环会失败?
- C++需要弄清楚为什么这个 for 循环不起作用
- 使用指针和引用,无法弄清楚为什么DFS无限重复
- 为什么编译器无法弄清楚构造函数实际上是 constexpr?
- 无法弄清楚为什么我的打印阵列要替换元素
- 我的程序不断抛出编译错误,我无法弄清楚为什么会发生错误
- 我在while循环中遇到问题,我只是无法弄清楚为什么它无法按预期工作
- 无法弄清楚为什么这个Arduino代码不起作用?
- 我正在制作一个刽子手游戏,我需要帮助弄清楚为什么它不能完全工作
- 无法弄清楚为什么只从文件中读取一行矩阵以及为什么我无法将 2D 数组传递给函数
- 我很难弄清楚为什么我的双重链接列表会崩溃,我可以找到一些方向
- 无法弄清楚为什么我会得到GL_INVALID_OPERATION
- 我需要帮助弄清楚为什么此C 程序不会使用GNU CC编译器在代码块中构建和运行
- 我无法弄清楚为什么我生成的随机数没有正确存储
- 无法弄清楚为什么我的 str2Int 函数返回 0
- 无法弄清楚为什么代码行会引发异常