【问题标题】:How to stop recursion?如何停止递归?
【发布时间】:2013-05-18 19:43:21
【问题描述】:

下面的代码是to find the path in a tree that adds up to a given sum...我在这里做的是enqueue所有节点的值到一个数组path中,如果条件满足递归打印它......

void checkSum(NODE* root, int path[], int len, int sum){

     if(root == NULL) return;

     path[len] = root->data;
     len++;

     if(sum - root->data == 0){ 
            sum -= root->data;
            cout<<"\nSum equals..."; 
            printPaths(path, len); 
     }
     else if(sum - root->data > 0){
          sum -= root->data;
          checkSum(root->left, path, len, sum);    
          checkSum(root->right, path, len, sum);
     }else { return; }
}

我想知道的是,有没有其他方法可以在不使用任何数据结构的情况下打印路径(至少一个)???

类似这样的......

void checkSum_second(NODE* root, int sum){

     if(root == NULL) return;

     if(sum - root->data == 0) {  
          //do something
     }     
     else if(sum - root->data > 0){
          sum -= root->data;                 
     }else return;


     checkSum_second(root->left, sum);
     checkSum_second(root->right, sum);     
     cout<<"\nvalue..."<<root->data;
}

考虑一棵树

           1
       2       3
    4    5   6   7

如果sum = 7 checkSum_second(root-&gt;left, sum); 被执行三次,即直到节点 4,在这里我们是否可以停止一切并只打印堆栈(即清空它)......

【问题讨论】:

    标签: c++ data-structures recursion


    【解决方案1】:

    如果您不想保存路径,请在达到您的数字 (7) 后,将图形向上移动并打印途中的每个点头。

    编辑:这是有关如何执行此操作的代码 请注意,这将:

    1. 自下而上打印路径
    2. 打印所有可能的路径

    这是代码

    void checkSum_second(NODE* originalRoot, NODE* root, int sum){
    
     if(root == NULL) return;
    
     if(sum - root->data == 0) { 
          //do something 
          NODE* tmp = root;
          while (tmp != originalRoot) {
               print(tmp->data);
               tmp = tmp->parent;
          }
     }     
     else if(sum - root->data > 0){
          sum -= root->data;                 
     }else return;
    
    
     checkSum_second(originalRoot,root->left, sum);
     checkSum_second(originalRoot,root->right, sum);     
     cout<<"\nvalue..."<<root->data;
    

    }

    【讨论】:

      【解决方案2】:

      这应该把它颠倒打印出来,但如果你不想要数据结构,我认为没有其他方法。

      找到路径后返回true

      void checkSum_second(NODE* root, int sum){
           if(root == NULL) return false;
      
           if(sum - root->data == 0)
           {
                cout<<"\nvalue..."<<root->data;
                return true;
           }
           else if(sum - root->data > 0)
                sum -= root->data;
           else return false;
      
           // if first is true, second won't get evaluated (it's the way || works)
           // if we found a path, print the current node and return true
           if (checkSum_second(root->left, sum) ||
               checkSum_second(root->right, sum))
           {
             cout<<"\nvalue..."<<root->data;
             return true;
           }
           return false;
      }
      

      【讨论】:

        【解决方案3】:

        要提前终止递归,您需要在调用链上传递某种信号。对于您的情况,您可以将返回类型更改为bool,并返回true,表示搜索已终止,无需进一步处理:

        bool checkSum(NODE* root, int path[], int len, int sum) {
             if(root == NULL) return false;
             path[len] = root->data;
             len++;
             if (sum - root->data == 0){ 
                  sum -= root->data;
                  cout<<"\nSum equals..."; 
                  printPaths(path, len);
                  return true;
             } else if (sum - root->data > 0) {
                  sum -= root->data;
                  if (checkSum(root->left, path, len, sum)) {
                      return true;
                  }
                  if (checkSum(root->right, path, len, sum)) {
                      return true;
                  }
             }
             return false;
        }
        

        请注意,在上面的代码中,递归调用仅在先前的调用继续返回 false 时继续。从调用返回的第一个 true 被向上发送到调用链,导致整个调用链终止。

        【讨论】:

        • 也可以使用longjmp(鉴于可能使用 RAII,不推荐用于 C++)或使用异常机制跳回堆栈。
        • @VladLazarenko 对,longjmp 不应该精确地用于 RAII 原因。另一方面,不应使用异常,除非调用链因异常情况而终止(例如,在意外的地方发现空值,或同样异常的情况)。
        • 希望longjmp 很快会使用 Itanium ABI 并展开堆栈(即像 NPTL 在 Linux 上的线程取消)。
        • 我相信 OP 想要摆脱 int path[] 并在他前进的过程中打印路径 - 来自问题 - "is there any other way that I can print the path (at least one) without using any data structures?"。不确定那个或标题(或两者)是否是实际问题。
        猜你喜欢
        • 2019-10-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-30
        • 2019-03-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多