LEE Hau Chon
LEE Hau Chon

Reputation: 445

How to do unspecific number of nested loop using only loops

Let's say I have a function that implement looping and recursion:

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);
       }
   }
}

Using this type of design, I can do unspecific number of nested loop. It result something like this:

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
   }
}

But from what I read online (this question), seem like most of them agree that what can be done using recursion can be done using looping also (if getting the output is the only concern). The answer/comment says that "Basically, doing loops instead of recursion means to manually handle the stack", but practically, how do I "handle the stack" in this scenario? Do I need pointer or any other things to do that?

Some might ask "why use loop when u can done with recursion? In what situation you are restricted to use only loop? ". Well, I am just curious of how this thing can be done using only loops without recursion.

Can someone provide a design of :

  1. loop only
  2. without any recursion
  3. can perform an unspecific number of nested looping

Thank you in advance.

EDIT:

Let's consider we have a positive integer parameter nested that tells the program how many nested loop is needed.

For example, the algorithm will result something like this if nested == 3:

while(condition1)
    while(condition2)
        while(condition3)
             //do something

If nested == 4

while(condition1)
    while(condition2)
        while(condition3)
            while(condition4)
                //do something

If nested == 0

//do something

Image description:

enter image description here

Let's take looping a tree-like structure as an example. In this image, the Height of tree is 2, which also represent amount of nested loop needed and nested in previous description , and it is also balanced binary tree, so by using loops only, we can do something like this.

int i =0;
while(i<2)
{
    int j =0;
    while(j<2)
    {
       //do something, ie:
       std::cout<<arr[i][j];
       j++;
    }
    i++;
}

in which i represent index of Level 1, j represent index of Level 2.

But what if the Height of tree, or depth of tree is unknown until the execution and not balanced? The tree can have 3 level on the first path down, and 5 level on the second path down. The only solution I can think of is implementing both recursion and loops, look something like the code I stated at the first code section. So without using recursion, how can we loop through a tree like structure which height or depth is unknown, it not necessary balanced and starting from the root?

Upvotes: 0

Views: 220

Answers (1)

MBo
MBo

Reputation: 80287

General scheme:

Initialize state storage
Loop:
   Extract state and  check - should we continue?
       Yes: 
            do work
            change state
       No:
            break

For your example state storage contains list of some conditions. At every level we have index of level as state and can check corresponding condition.

Tree structure like your picture shows, might be traversed both with recursion and with iterative approach using stack (or queue) storage.


Consider recursive and iterative versions of QuickSort (implementation taken from geeksforgeek).

The second version implements explicit stack and reproduces implicit operations of recursive one.

The only difference I see - iterative version does not put 0/1-length ranges on the stack while recursive version makes recursive call always but immediately returns in case 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; 
        } 
    } 
} 

Upvotes: 3

Related Questions