何海涛算法面试题感悟之四:二元树…

题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。

例如输入整数22和如下二元树

                                            10
                                            \
                                             12
                                        /    
                                         

则打印出两条路径:10, 1210, 5, 7

二元树结点的数据结构定义为:

struct BinaryTreeNode // a node in the binary tree
{
      int              m_nValue; // value of node
      BinaryTreeNode  *m_pLeft;  // left child of node
      BinaryTreeNode  *m_pRight; // right child of node
};

这里其实用到了树的深度搜索,在深度搜索的过程中将遍历到的每一个节点的值相加,当扫描到叶节点的时候, 判断和是否为期待和,如果是,则打印出路径,否则,不打印,然后将该节点从栈中删除,便返回到父节点的其他节点,继续操作。

void FindPath
(
      BinaryTreeNode*   pTreeNode,    // a node of binary tree
      int               expectedSum,  // the expected sum
      std::vector<int>& path,         // a path from root to current node
      int              currentSum    // the sum of path
)
   // 如果当前节点为空,则返回
      if(!pTreeNode)
            return;
     // 当前和的值为当前节点的值加上当前和的值,并且将其压入栈中
      currentSum += pTreeNode->m_nValue;
      path.push_back(pTreeNode->m_nValue);

      //判断该节点是否在叶节点,如果是叶节点,打并且路径上节点的和值等于期待的和,那么打印此这条路径
      bool isLeaf = (!pTreeNode->m_pLeft && !pTreeNode->m_pRight);
      if(currentSum == expectedSum && isLeaf)
      {    
           std::vector<int>::iterator iter = path.begin();
          
for(; iter != path.end(); ++ iter)
                 std::cout << *iter << '\t';
           std::cout << std::endl;
      }

      //如果当前节点不是叶节点,那么可以遍历它的左右子树,这里就用到了递归的思想
      if(pTreeNode->m_pLeft)
            FindPath(pTreeNode->m_pLeft, expectedSum, path, currentSum);
      if(pTreeNode->m_pRight)
            FindPath(pTreeNode->m_pRight, expectedSum, path, currentSum);

     // 最后,必须把当前节点弹出栈,回朔到父节点     

    path.pop_back();
} 

由此看来,本道题目其实就是考察树的深度搜索和栈的先进先出这条性质,当某一条路径打印完毕之后,函数的最后一条语句就是起这样一条作用,将以当前节点为根的路径删除,有的读者可能会有疑问,为什么将当前节点弹出就等于删除了以当前节点为根的路径了,因为这里用到了递归,将当前节点弹出之前,其实它的子树的所有节点都已经进行过path.pop_back();操作了,最后该路径只剩下当前节点了。。。

本篇文章对应何海涛博客http://zhedahht.blog.163.com/blog/static/254111742007228357325/

略有改动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值