我有以下递归算法需要编译到迭代过程中。 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
}
}
我想将这个逻辑重构为迭代算法。 关于这个的任何提示?
答案 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,将它们添加到向量的末尾并执行++索引。
最终会指向该向量/数组/中的所有树节点。
然后你只是迭代它,画东西等等。