问题
This is not a case where I can use both without problems, because I'm already convinced that loops are much easier to understand and I try to always use them. But then I stumble upon this (C++ function for binary search tree):
Node* Insert(Node* &rootptr,Node* data) {
if (rootptr == nullptr) {
rootptr = data;
}
else if (data->number <= rootptr->number) {
rootptr->leftptr = Insert(rootptr->leftptr,data);
}
else {
rootptr->rightptr = Insert(rootptr->rightptr,data);
}
return rootptr;
}
And my mind gets blown when I try to think how to make it through loops. Well, why to suffer then? Use recursion if it's the case. But the fact that my mind gets blown actually shows how harmful recursion is, because when you look at it you don't understand what it exactly does. Yes, it's neat, but it's a dangerous kind of neat, when it does several things at the same time and you don't really comprehend what is happening.
So in my opinion there are 3 cases: when recursion is simple and there's no reason to cope with it, when recursion is complex and you make your code unreadable, and of course some cases when there's no other way, so you just have to use it, like with Ackermann function. Why to use it then (besides some specific cases)?
回答1:
Recursion can be a lot more clear. The only worry with recursion is that you can smash the stack if you use it too much. For example linux typically has a 2MB stack so you don't want to recurse millions of lines deep. Recursing a binary tree that is only O(log n) deep is probably fine.
In this case it is fairly simple to replace it with a loop like the following, but it is not always the case.
Node* Insert(Node* &rootptr,Node* data) {
Node** p=&rootptr;
while ((*p) != nullptr) {
if (data->number <= (*p)->number) {
p=&(*p)->leftptr;
}
else {
p=&(*p)->rightptr;
}
}
(*p) = data;
return data;
}
回答2:
You are on the wrong track here: understanding recursion needs some studying, in order to get it right into your head, but once you get the grip, you will understand the elegancy of the system, so the danger will easily go away.
Does this mean that there's no danger at all in recursion? Well, there's one very important risk: each time a recursive function is called, it gets added to the call stack. When you're dealing with single recursion (like fact(n) = n*fact(n-1)), then the problem might be limited, but dealing with multiple recursion calls (like in a binary tree), the amount of function calls on the stack grows exponentially, which might blow up your call stack and cause your program to crash.
来源:https://stackoverflow.com/questions/62392275/should-i-avoid-recursion-everywhere-its-possible