用递归代替 while 循环
Replacing while-loop with recursion
快速简单的问题:
这是:
private static void SetupConnection()
{
try
{
TcpClient client = new TcpClient(myServer, myPort);
//Do whatever...
}
catch (SocketException)
{
//Server is closed. Retry in 10 minutes.
Thread.Sleep(600000);
SetupConnection();
}
一个可行的替代方案:
private static void SetupConnection()
{
while (true)
{
try
{
TcpClient client = new TcpClient(myServer, myPort);
//Do whatever...
break;
}
catch (SocketException)
{
//Server is closed. Retry in 10 minutes.
Thread.Sleep(600000);
}
}
}
虽然第二个看起来 "cleaner" 我仍然很好奇第一个是否也可以接受 – 如果不是,那为什么不呢?
递归在这种情况下很糟糕,因为如果您的程序运行时间过长并且重试连接,您最终会遇到 WhosebugException。
为什么递归不好?
您需要了解什么是调用堆栈。
这是一个保存在内存中的堆栈。每次调用新方法时,该方法的引用和参数都会添加到此堆栈中。该堆栈将保存在内存 (RAM) 中。
使用递归,如果你在没有任何边界条件的情况下继续调用方法,堆栈将继续增长。
一段时间后,它将处于无法接受任何进一步条目的状态,因为没有足够的内存来容纳它。
那时你会得到 "Stack Overflow Exception"。
我们可以在不使用递归的情况下重写每个递归算法吗?
是的,你可以。该方法通常称为 "Iterative approach".
在任何情况下,您都可以使用辅助堆栈/列表/变量组来保存您在递归中使用的参数。
然后你可以迭代这些变量,直到达到边界条件。
这样,您无需一次又一次地调用您的方法即可获得相同的结果。
使用这种方法总是更好。
那为什么要写递归算法呢?
有时候,递归算法很容易阅读。迭代方法代码可能不容易阅读,这就是人们多次尝试编写递归代码的原因。
您可以根据以下两点决定是使用迭代方法还是递归方法:
输入样本
代码可维护性
如果你还想写递归方法,不要忘记添加递归停止的边界条件。
例如。树遍历代码(pre order, in order , post order)写递归算法更容易理解。
只要您对树中的节点/级别数量有一定限制,这就可以正常工作。如果您已经知道您的树非常庞大,您可能会采用迭代方法。
希望这能帮助您更好地理解这些方法。
快速简单的问题:
这是:
private static void SetupConnection()
{
try
{
TcpClient client = new TcpClient(myServer, myPort);
//Do whatever...
}
catch (SocketException)
{
//Server is closed. Retry in 10 minutes.
Thread.Sleep(600000);
SetupConnection();
}
一个可行的替代方案:
private static void SetupConnection()
{
while (true)
{
try
{
TcpClient client = new TcpClient(myServer, myPort);
//Do whatever...
break;
}
catch (SocketException)
{
//Server is closed. Retry in 10 minutes.
Thread.Sleep(600000);
}
}
}
虽然第二个看起来 "cleaner" 我仍然很好奇第一个是否也可以接受 – 如果不是,那为什么不呢?
递归在这种情况下很糟糕,因为如果您的程序运行时间过长并且重试连接,您最终会遇到 WhosebugException。
为什么递归不好?
您需要了解什么是调用堆栈。
这是一个保存在内存中的堆栈。每次调用新方法时,该方法的引用和参数都会添加到此堆栈中。该堆栈将保存在内存 (RAM) 中。
使用递归,如果你在没有任何边界条件的情况下继续调用方法,堆栈将继续增长。
一段时间后,它将处于无法接受任何进一步条目的状态,因为没有足够的内存来容纳它。
那时你会得到 "Stack Overflow Exception"。
我们可以在不使用递归的情况下重写每个递归算法吗?
是的,你可以。该方法通常称为 "Iterative approach".
在任何情况下,您都可以使用辅助堆栈/列表/变量组来保存您在递归中使用的参数。
然后你可以迭代这些变量,直到达到边界条件。
这样,您无需一次又一次地调用您的方法即可获得相同的结果。 使用这种方法总是更好。
那为什么要写递归算法呢?
有时候,递归算法很容易阅读。迭代方法代码可能不容易阅读,这就是人们多次尝试编写递归代码的原因。
您可以根据以下两点决定是使用迭代方法还是递归方法:
输入样本
代码可维护性
如果你还想写递归方法,不要忘记添加递归停止的边界条件。
例如。树遍历代码(pre order, in order , post order)写递归算法更容易理解。 只要您对树中的节点/级别数量有一定限制,这就可以正常工作。如果您已经知道您的树非常庞大,您可能会采用迭代方法。
希望这能帮助您更好地理解这些方法。