Data structures 在这种情况下,如何将递归修改为循环版本?

Data structures 在这种情况下,如何将递归修改为循环版本?,data-structures,compiler-construction,recursion,binary-tree,tail-recursion,Data Structures,Compiler Construction,Recursion,Binary Tree,Tail Recursion,我想修改下面的C++代码,使用循环代替递归。 我知道有两种方法可以修改它: 从代码中学习并生成循环算法。在本例中,我认为代码的含义是按级别顺序打印B(除叶外)和打印A(除根外)。对于二叉(搜索)树,如何在循环中从叶遍历到根(没有指向父级的指针) 使用堆栈模拟堆栈上的进程。如果我来不了,你能帮我说一些有用的想法吗 void func(const Node& node) { if (ShouldReturn(node)) { return; } f

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

  • 从代码中学习并生成循环算法。在本例中,我认为代码的含义是按级别顺序打印B(除叶外)和打印A(除根外)。对于二叉(搜索)树,如何在循环中从叶遍历到根(没有指向父级的指针)

  • 使用堆栈模拟堆栈上的进程。如果我来不了,你能帮我说一些有用的想法吗

    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();
    }
    
    void func(常量节点和节点){
    if(ShouldReturn(节点)){
    返回;
    }
    对于(int i=0;i

  • 假设您使用的是C++

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

  • 若节点是叶,则什么也并没有
  • 否则,对每个子级执行相同的操作,然后在每个子级之后打印一个
  • 然后打印B
  • 如果我稍微调整一下代码呢。调整只适用于迭代方式

    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);
        }
    }
    
    void func(常量节点和节点){
    if(ShouldReturn(node))返回;
    PrintB();
    对于(int i=0;i
    这将颠倒打印A&B的顺序,我希望我没有错:D 现在我想要两个向量

    // 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();
         }
    }
    
    //让我们定义一个枚举
    typedef枚举{fprintA,fprintB}printType;
    void func(常量节点和节点){
    矢量图;
    向量stackOfNodes;stackOfNodes.push_back(节点);
    bool first=true;//因为我们不需要在根之前打印a。
    而((int)stackOfNodes.size()>0){
    常量节点&fNode=stackOfNodes.back();
    stackOfNodes.pop_back();
    if(!first)stackOfPrints.push_back(fprintA);//如果不是根printA。
    第一个=假;
    如果(ShouldReturn(fNode))继续;
    打印堆栈。向后推(fprintB);
    //这里按相反的顺序推送节点,以便在堆栈中以正确的顺序进行处理。
    对于(int i=(int)fNode.children_size()-1;i>=0;--i){
    stackOfNodes.push_back(fNode.child(i));
    }
    }
    //以相反的顺序打印stackOfPrints(记住我们更改了代码,最初以相反的方向打印As&Bs)
    //这样,它将使函数按正确的要求顺序打印它们
    而((int)stackOfPrints.size()>0){
    开关(stackOfPrints.back()){
    案例fprintA:printA();break;
    案例fprintB:printB();中断;
    默认:中断;
    };
    stackOfPrints.pop_back();
    }
    }
    

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

    此函数“ShouldReturn(node)”的作用是什么。请详细阐述一下问题陈述。您希望在程序中实现什么。您的方法是将rec传输到tail rec,然后循环~谢谢~我有另一个想法:在案例1(-3)-2-4中,func1(1)=f1{f2{f4{blablablabla}//f4A4}//f2A2 f3{blablabla}//f3A3}//f1,然后定义“{fk”:push和“}fk”:if(ShouldReturn(node))return;BK;=>pop();=>Ak。现在,如果您有一个循环版本的DFS,它很容易工作!