将迭代算法转换为递归算法

时间:2012-10-09 07:22:16

标签: algorithm recursion

我编写了一个代码,使用队列(数组)在Level Order中打印树。

    void printLevelOrder(node *root) {
         node* queue[10];
         node*t=root;
         int y=0;
         queue[y]=t;
         for(int i=0;i<10;i++)
         {
                 printf("%d,",queue[i]->val); 

                 t=queue[i];
                 if((t->left)!=NULL){
                 queue[++y]=t->left;
                 }
                 if((t->right)!=NULL){
                 queue[++y]=t->right;
                 }
         } 
}

我想将方法​​转换为递归方法。 我试过,但我没有得到正确的解决方案。是否可以将此类问题转换为使用递归调用?

4 个答案:

答案 0 :(得分:1)

可以使这个递归,但在这种情况下,结果可能看起来像上面执行的代码中的循环体,然后为队列中的下一个元素调用自身。 可能将其转换为树遍历算法中更常见的一种递归,其中递归方法为其作为参数接收的子节点调用自身。因此没有预期的性能提升 - 您仍然需要队列或类似的结构 - 我并没有真正看到执行转换的重点。

答案 1 :(得分:0)

我不确定这是否是您正在寻找的,但它是部分递归。

void print_level_part(node* p, level) {
    if(p) {
        if(level==1) {
            printf("%d", p->val);
        } else {
            print_level_part(p->left, level-1);
            print_level_part(p->right, level-1);
        }
    }
}

//the loop in main which does the main printing.
for(int i=0; i<n; ++i) {
    print_level_part(root, i);
}

如果您想要完全递归的解决方案,那么我可能会建议您更改for递归函数中的main循环。

答案 2 :(得分:0)

这是Qnan所谈论的一个例子:

void printNext(node **queue,int i,int y)
{
  if (i==y) return;

  node *t = queue[i++];
  printf("%d,",t->val);

  if (t->left)  queue[y++] = t->left;
  if (t->right) queue[y++] = t->right;

  printNext(queue,i,y);
}

void printLevelOrder(node *root)
{
  node *queue[10]; /* be careful with hard-coded queue size! */
  int y=0, i=0;

  queue[y++]=root;
  printNext(queue,i,y);
  printf("\n");
}

答案 3 :(得分:0)

据我所知,在“级别顺序”中打印树实际上是给定树的BFS遍历,递归不适合。递归是DFS非常适合的方法。

递归内部使用堆栈(LIFO结构),而BFS使用队列(FIFO结构)。如果根的解决方案依赖于(结果,或只是遍历顺序)子树的解,则树算法适用于递归。递归转到树的“底部”,并从底部向上解决问题。由此,预订,有序和后序遍历可以作为递归完成:

  • 预购:打印根,打印左子树,打印正确的子树
  • 按顺序:打印左子树,打印根,打印正确的子树
  • 后期订单:打印左子树,打印右侧子树,打印根
但是,级别顺序不能在“为root做某事,为每个子树做某事”中分解。唯一可能的“递归”实现将遵循@Qnan建议,并且,正如他所说,没有多大意义。

然而,可能的是,将任何递归算法转换为迭代算法相当优雅。由于内部递归实际上与堆栈一起工作,因此在这种情况下唯一的技巧是使用自己的堆栈而不是系统堆栈。这种递归和迭代实现之间的一些细微差别将是:

  • 使用迭代,可以节省函数调用的时间
  • 使用递归,您通常会获得更直观的代码
  • with recursive ,为每个函数调用的返回地址分配额外的内存
  • 使用迭代,分配内存,并确定内存的分配位置