在这种情况下如何修改循环版本的递归?

时间:2012-09-17 12:43:15

标签: data-structures compiler-construction recursion binary-tree tail-recursion

我想修改下面的c ++代码,使用循环而不是递归。 我知道有两种方法可以修改它:

  1. 从代码中学习并制作循环算法。在这种情况下,我认为代码的含义是按级别顺序printB(除叶子)和printA(期望根)。对于二进制(搜索)树,如何在循环中从叶子到根遍历它(没有指向父节点的指针)?

  2. 使用堆栈模仿堆栈上的进程。在这种情况下,我无法成功,你能帮我说一些有用的想法吗?

    void func(const Node& node) {
    
        if (ShouldReturn(node)) {
            return;
        }
    
        for (int i = 0; i < node.children_size(); ++i) {
            const Node& child_node = node.child(i);
            func(child_node);
            PrintA();
        }
    
        PrintB();
    }
    

1 个答案:

答案 0 :(得分:0)

假设您使用的是C ++

对于堆栈部分,假设代码执行以下操作。

  1. 如果Node是叶子,没有。
  2. 对每个孩子都这样做,然后在每个孩子之后再打印。
  3. 然后printB。
  4. 那么如果我调整代码的话会怎么样呢。调整只适合迭代方式。

    void func(const Node& node) {
        if(ShouldReturn(node)) return;
        PrintB();
        for(int i = 0; i < node.children_size(); ++i) {
            printA();
            const Node& child_node = node.child(i);
            func(child_node, false);
        }
    }
    // This way should make it print As & Bs in reverse direction.
    // Lets re-adjust the code even further.
    
    void func(const Node& node, bool firstCall = true) {
        if(!firstCall) printA; //Placed that here, as printA is always called if a new Node is called, but not for the root Node, that's why I added the firstCall.
        if(ShouldReturn(node)) return;
        PrintB();
        for(int i = 0; i < node.children_size(); ++i) {
            const Node& child_node = node.child(i);
            func(child_node, false);
        }
    }
    

    这应该扭转印刷A&amp;的顺序。 B,我希望我没错:D 所以,现在我想要2个载体。

    // Lets define an enum
    typedef enum{fprintA, fprintB} printType;
    
    void func(const Node& node){
         vector<printType> stackOfPrints;
         vector<Node*> stackOfNodes; stackOfNodes.push_back(node);
         bool first = true; //As we don't need to printA before the root.
         while ((int)stackOfNodes.size() > 0){
             const Node& fNode = stackOfNodes.back();
             stackOfNodes.pop_back();
             if (!first) stackOfPrints.push_back(fprintA); // If not root printA.
             first = false;
             if(ShouldReturn(fNode)) continue;
             stackOfPrints.push_back(fprintB);
             // here pushing the Nodes in a reverse order so that to be processed in the stack in the correct order.
             for(int i = (int)fNode.children_size() - 1; i >= 0; --i){
                   stackOfNodes.push_back(fNode.child(i));
             }
         }
    
         // Printing the stackOfPrints in reverse order (remember we changed the code, to initially print As & Bs in reverse direction) 
         // this way, it will make the function print them in the correct required order
         while((int)stackOfPrints.size() > 0){
             switch(stackOfPrints.back()){
                case fprintA: printA(); break;
                case fprintB: printB(); break;
                default: break;
             };
             stackOfPrints.pop_back();
         }
    }
    

    我希望我能正确编写代码。 :)我希望它有所帮助。