提问人:Avi Moreno 提问时间:11/16/2023 最后编辑:Avi Moreno 更新时间:11/18/2023 访问量:72
我的递归函数即使在达到基本情况后也会继续运行
my recursive function keeps going even after reaching the base case
问:
这是一个 C++ 递归函数,它应该在链表中查找路径。到达基本情况后我无法完成。即使在返回后,它也会继续前进;
void navigateGraph(ListNode *currentNode, ListNode *destinationNode, string currentPath) {
// Base case
if (currentNode == destinationNode) {
cout << "Ending reached!" << endl;
cout << "Path taken: " << currentPath << destinationNode->name << endl;
return;
}
currentNode->visited = 1;
if (currentNode->up != nullptr && currentNode->up->visited == 0) {
cout << "Moving upward to " << currentNode->up->name << endl;
navigateGraph(currentNode->up, destinationNode, currentPath + currentNode->name + " ");
}
if (currentNode->left != nullptr && currentNode->left->visited == 0) {
cout << "Moving left to " << currentNode->left->name << endl;
navigateGraph(currentNode->left, destinationNode, currentPath + currentNode->name + " ");
}
if (currentNode->down != nullptr && currentNode->down->visited == 0) {
cout << "Moving downward to " << currentNode->down->name << endl;
navigateGraph(currentNode->down, destinationNode, currentPath + currentNode->name + " ");
}
if (currentNode->right != nullptr && currentNode->right->visited == 0) {
cout << "Moving right to " << currentNode->right->name << endl;
navigateGraph(currentNode->right, destinationNode, currentPath + currentNode->name + " ");
}
if (currentNode->visited == 1) {
cout << "Current path from " << currentNode->name << " ends" << endl;
}
}
我怎样才能使递归在基本情况之后停止。
答:
解决您突出显示的问题的一个快速解决方案是使递归函数返回一些东西:指示是否找到(并输出)结束节点。所以这可能是一个布尔值。然后,在进行递归调用的每个位置,都应检查其返回值。如果表示已找到路径,则立即返回,再次表示成功。否则,让代码像现在一样继续,以便可以探索其他可能性。
这里有一个剧透,以防你无法让它工作:
bool recursiveFunction(ListNode *current, ListNode *ending, string path) { //base case if (current == ending) { cout << "Destination reached!" << endl; cout << "Path was: " << path << ending->name << endl; //delete current; didn't work either return true; // Indicate success } current->visited = 1; if (current->up != nullptr && current->up->visited == 0) { cout << "Going up to " << current->up->name << endl; if (recursiveFunction(current->up, ending, path + current->name + " ")) return true; } if (current->left != nullptr && current->left->visited == 0) { cout << "Going left to " << current->left->name << endl; if (recursiveFunction(current->left, ending, path + current->name + " ")) return true; } if (current->down != nullptr && current->down->visited == 0) { cout << "Going down to " << current->down->name << endl; if (recursiveFunction(current->down, ending, path + current->name + " ")) return true; } if (current->right != nullptr && current->right->visited == 0) { cout << "Going right to " << current->right->name << endl; if (recursiveFunction(current->right, ending, path + current->name + " ")) return true; } if (current->visited == 1) { cout << current->name << " ends" << endl; } return false; }
然而,实际上有一种更优雅的算法(以我的拙见),你不必作为参数传递:只有在找到结束节点之后,你才开始识别节点在路径上,这应该在从递归中解脱出来时发生。path
无关紧要,但我会尽量避免您在处理四个方向时重复代码。对通用代码使用帮助程序函数。
再次剧透这个想法:
bool recursiveFunction(ListNode *current, ListNode *ending); // Helper function to avoid code repetition bool visitNeighbor(ListNode *neighbor, string direction, ListNode *ending) { if (neighbor && !neighbor->visited) { cout << "Going " << direction << " to " << neighbor->name << endl; return recursiveFunction(neighbor, ending); } return false; } bool recursiveFunction(ListNode *current, ListNode *ending) { //base case if (current == ending) { // Output the success message. The actual nodes on the path will follow later... cout << "Destination reached, path was:"; } current->visited = 1; bool found = current == ending || visitNeighbor(current->up, "up", ending) || visitNeighbor(current->left, "left", ending) || visitNeighbor(current->down, "down", ending) || visitNeighbor(current->right, "right", ending); if (found) { // Output the node on the path (in reverse order) cout << " " << current->name; return true; // ... and indicate success } cout << current->name << " ends" << endl; return false; }
评论
else if
if
current->visited = 1;
if (current->visited == 1)
true
true