这段代码是否遵循递归的定义?

时间:2010-06-17 10:08:01

标签: c++ recursion

我有一段代码,我怀疑它是通过其定义实现的递归。我的理解是代码必须调用自身,完全相同的功能。我还质疑是否以这种方式编写代码会增加额外的开销,这可以通过使用递归来看到。你有什么想法?

class dhObject
{
public:
   dhObject** children;
   int numChildren;
   GLdouble linkLength; //ai 
   GLdouble theta; //angle of rot about the z axis
   GLdouble twist; //about the x axis
   GLdouble displacement; // displacement from the end point of prev along z
   GLdouble thetaMax;
   GLdouble thetaMin;
   GLdouble thetaInc;
   GLdouble direction;

   dhObject(ifstream &fin)
   {
      fin >> numChildren >> linkLength >> theta >> twist >> displacement >> thetaMax >> thetaMin;
      //std::cout << numChildren << std::endl;
      direction = 1;
      thetaInc = 1.0;
      if (numChildren > 0)
      {
         children = new dhObject*[numChildren];
         for(int i = 0; i < numChildren; ++i)
         {
            children[i] = new dhObject(fin);
         }
      }
   }

   void traverse(void)
   {
      glPushMatrix();
      //draw move initial and draw
      transform();
      draw();
      //draw children
      for(int i = 0; i < numChildren; ++i)
      {
         children[i]->traverse();
      }
      glPopMatrix();
   }

   void update(void)
   {
      //Update the animation, if it has finished all animation go backwards
      if (theta <= thetaMin)
      {
         thetaInc = 1.0;
      } else if (theta >= thetaMax)
      {
         thetaInc = -1.0;
      }
      theta += thetaInc;
      //std::cout << thetaMin << " " << theta << " " << thetaMax << std::endl;
      for(int i = 0; i < numChildren; ++i)
      {
         children[i]->update();
      }
   }

   void draw(void)
   {
      glPushMatrix();
      glColor3f (0.0f,0.0f,1.0f);
      glutSolidCube(0.1);
      glPopMatrix();
   }

   void transform(void)
   {
      //Move in the correct way, R, T, T, R
      glRotatef(theta, 0, 0, 1.0);
      glTranslatef(0,0,displacement);
      glTranslatef(linkLength, 0,0);
      glRotatef(twist, 1.0,0.0,0.0);
   }
};

5 个答案:

答案 0 :(得分:6)

这是定义/挑剔的问题。在这个C函数中:

void traverse( tree * t ) {
    if ( t != 0 ) {
        traverse( t->right );
        traverse( t->left );
    }
}

函数是递归的吗?我会说是的,即使它是在不同的对象上调用的。所以我会说你的代码也是递归的。举一个更极端的例子:

unsigned int f( unsigned int n ) {
    if ( n = 0 ) {
       return 0; 
    }
    else {
       return f( n - 1 );   // XXX
    }
}

在XXX上调用函数的事情显然与最初调用的函数不同。但我认为每个人都会同意这是一个递归函数。

答案 1 :(得分:5)

是的,因为你有自己的某些功能。根据定义,它是直接递归。如果你有函数A()调用函数B(),函数B()依次(直接或间接)调用函数A(),你也可以有间接递归试。

答案 2 :(得分:1)

看起来像traverse()和update()方法中的递归,深度由对象集合的物理几何控制。

如果这是你的实际课程,我会推荐一些东西:

  1. 在使用之前检查numChildren的上限,以免有人错误地传入一个非常大的数字。

  2. 如果这将在线程环境中使用,您可能希望同步对子对象的访问。

  3. 考虑使用容器而不是分配数组。我没有看到析构函数,所以如果这个对象被删除,你就会泄漏数组存储和子节点的内存。

答案 3 :(得分:1)

如果您担心的是递归的开销,那么重要的是测量堆栈的深度。如果您的堆栈是100个深度调用,那么无论您是否以递归方式工作都无关紧要。

答案 4 :(得分:0)

调用这些方法之一(遍历或更新)将具有为每个孩子调用相同方法的效果。所以,这些方法不是递归的。相反,它是一种递归算法:它以递归方式应用于对象的逻辑树上。

调用堆栈的深度直接由算法运行的数据结构决定。

真正发生的是这个(伪代码):

Function Traverse(object o)
{
   [do something with o]

   Foreach(object child in o.Children)
       Traverse(child);

   [do something with o]
}