I have following recursive algorithm needed to redactor into iterative process. CvSeq is a tree structure.Where contour->h_next gives the next node in the same level. contour->v_next gives the next contour in level below.(child node)
void helperParseCurves(CvSeq* contour, int level) {
if(contour->h_next != NULL) {
helperParseCurves(contour->h_next, level);
}
if(contour->v_next != NULL) {
helperParseCurves(contour->v_next, level+1);
}
//Process the nodes in contour
for(int i=0; i<contour->total; i++){
CvPoint* p = CV_GET_SEQ_ELEM(CvPoint, contour, i);
//Paint the point p
}
}
I want to refactor this logic into iterative algorithm. Any tips on this?
Initialize the accumulator before the while-loop. Use the negation of the base-case condition as the loop's condition. Use the recursive function's body (except the recursive call) as the body of the while-loop. After the loop, apply the base-case update of the accumulator and return its value.
Any recursive algorithm can be rewritten to use loops instead. The opposite is also true. Any iterative algorithm can be written in terms of recursion only. expressiveness: some algorithms are just naturally simpler or easier to write with loops.
So, yes all-recursive code can be converted to iteration.
Recursion and iteration are both different ways to execute a set of instructions repeatedly. The main difference between these two is that in recursion, we use function calls to execute the statements repeatedly inside the function body, while in iteration, we use loops like “for” and “while” to do the same.
To traverse nodes w/o recursion you will need stack for saving previous states. [Recursion is actually using of stack as well...] :
struct StackData
{
CvSeq* contour;
int level;
int traversed;
};
const int traversed_l = (1 << 0);
const int traversed_r = (1 << 1);
const int stack_size = 50; // should be at leas max depth
StackData stack[stack_size];
int stack_p = 0;
void helperParseCurves(CvSeq* contour, int level) {
int traversed = 0;
while(contour)
{
if(contour->h_next != NULL && !(traversed & traversed_l)) { // down to left
assert(stack_p < stack_size); // and save current state
traversed |= traversed_l;
stack[stack_p].contour = contour;
stack[stack_p].level = level;
stack[stack_p].traversed = traversed;
++stack_p;
contour = contour->h_next;
traversed = 0;
continue;
}
if(contour->h_next != NULL && !(traversed & traversed_r)) { // down to right
assert(stack_p < stack_p); // and save current state
traversed |= traversed_r;
stack[stack_p].contour = contour;
stack[stack_p].level = level;
stack[stack_p].traversed = traversed;
++stack_p;
contour = contour->v_next;
level = level+1;
traversed = 0;
continue;
}
//Process the nodes in contour
for(int i=0; i<contour->total; i++){
CvPoint* p = CV_GET_SEQ_ELEM(CvPoint, contour, i);
//Paint the point p
}
// move up because either left and right nodes are NULL or already traversed
if(!stack_p) break; // we are at the top
contour = stack[stack_p].contour;
level = stack[stack_p].level;
traversed = stack[stack_p].traversed;
--stack_p;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With