将递归算法重构为迭代算法?

时间:2011-09-30 09:52:10

标签: c algorithm recursion

我有以下递归算法需要编译到迭代过程中。 CvSeq 是树结构。 contour-> h_next 为下一个节点提供相同级别。 contour-> v_next 给出下面级别的下一个轮廓。(子节点)

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
    }

}

我想将这个逻辑重构为迭代算法。 关于这个的任何提示?

2 个答案:

答案 0 :(得分:4)

要遍历没有递归的节点,您需要堆栈来保存以前的状态。 [递归实际上也在使用堆栈......]

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

答案 1 :(得分:1)

有一个CvSeq *的空向量/数组/队列。有一个索引/指针,首先指向它的开头(第一个元素将在哪里)。

从树的根开始,将其h_next和v_next添加到向量中。

然后当索引小于向量-1中的指针数时,取矢量[index]的h_next和v_next,将它们添加到向量的末尾并执行++索引。

最终会指向该向量/数组/中的所有树节点。

然后你只是迭代它,画东西等等。