假设我有一个实现循环和递归的函数:
public void Foo(int para1, int para2, bool is_leaf_node)
{
if(is_leaf_node)
//do something
else
{
//do something
while(some_condition)
{
//assign variable to be passed to next recursive call
Foo(para1_next,para2_next,is_leaf_node_next);
}
}
}
使用这种类型的设计,我可以执行不确定数量的嵌套循环。结果如下:
while(condition1)
{
//do something
while(condition2)
{
//do something
//keep nested looping
//until the last one (is_leaf_node == true) which don't have a while loop
}
}
但是从我在网上阅读的内容(this question)来看,似乎大多数人都同意使用递归可以完成的事情也可以使用循环来完成(如果仅关注输出)。答案/评论说:“基本上,执行循环而不是递归意味着手动处理堆栈”,但是实际上,在这种情况下我如何“处理堆栈”?我需要指针或其他任何东西吗?
有些人可能会问“为什么可以使用递归进行循环?在什么情况下您只能使用循环?”。好吧,我只是好奇如何仅使用循环而不进行递归来完成此任务。
有人可以提供以下设计吗?
先谢谢您。
编辑:
让我们考虑一个正整数参数nested
,它告诉程序需要多少个嵌套循环。
例如,如果nested == 3
,该算法将得出类似的结果:
while(condition1)
while(condition2)
while(condition3)
//do something
如果nested == 4
while(condition1)
while(condition2)
while(condition3)
while(condition4)
//do something
如果nested == 0
//do something
图片描述:
让我们以循环树状结构为例。在此图中,Height of tree
是2
,在前面的描述中也代表amount of nested loop needed
和nested
,它也是平衡的二叉树,因此仅使用循环,我们可以做这样的事情。
int i =0;
while(i<2)
{
int j =0;
while(j<2)
{
//do something, ie:
std::cout<<arr[i][j];
j++;
}
i++;
}
其中i
代表Level 1
的索引,j
代表Level 2
的索引。
但是如果Height of tree
或depth of tree
在执行之前是未知的并且不平衡,该怎么办?该树在第一条路径上可以具有3级,在第二条路径上可以具有5级。我能想到的唯一解决方案是实现递归和循环,看起来就像我在第一部分代码中提到的代码。因此,在不使用递归的情况下,如何遍历height
或depth
未知的树状结构,它不必从根开始就进行平衡?
答案 0 :(得分:3)
一般方案:
Initialize state storage
Loop:
Extract state and check - should we continue?
Yes:
do work
change state
No:
break
在您的示例中,状态存储包含一些条件的列表。在每个级别,我们都有级别索引作为状态,并且可以检查相应的条件。
如您的图片所示,树结构可能同时使用递归和with iterative approach using stack(或队列)存储。
考虑QuickSort的递归和迭代版本(实现taken from geeksforgeek)。
第二个版本实现显式堆栈并复制递归的隐式操作。
我看到的唯一区别-迭代版本不会在堆栈上放置0/1长度范围,而递归版本始终进行递归调用,但在if (l >= h)
情况下会立即返回
/* A[] --> Array to be sorted,
l --> Starting index,
h --> Ending index */
void quickSort(int A[], int l, int h)
{
if (l < h) {
/* Partitioning index */
int p = partition(A, l, h);
quickSort(A, l, p - 1);
quickSort(A, p + 1, h);
}
}
void quickSortIterative(int arr[], int l, int h)
{
// Create an auxiliary stack
int stack[h - l + 1];
// initialize top of stack
int top = -1;
// push initial values of l and h to stack
stack[++top] = l;
stack[++top] = h;
// Keep popping from stack while is not empty
while (top >= 0) {
// Pop h and l
h = stack[top--];
l = stack[top--];
// Set pivot element at its correct position
// in sorted array
int p = partition(arr, l, h);
// If there are elements on left side of pivot,
// then push left side to stack
if (p - 1 > l) {
stack[++top] = l;
stack[++top] = p - 1;
}
// If there are elements on right side of pivot,
// then push right side to stack
if (p + 1 < h) {
stack[++top] = p + 1;
stack[++top] = h;
}
}
}