二元树中和为某一值的全部路径

二元树中和为某一值的全部路径

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

             近期在这里看到一道面试题,看了题目和作者的解答后,感觉真是强大。

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

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

                                      二元树中和为某一值的全部路径

    则打印出两条路径:10, 12和10, 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
};

        作者的解答为:

///////////////////////////////////////////////////////////////////////// Find paths whose sum equal to expected sum///////////////////////////////////////////////////////////////////////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);      // if the node is a leaf, and the sum is same as pre-defined,       // the path is what we want. print the path      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 the node is not a leaf, goto its children      if(pTreeNode->m_pLeft)            FindPath(pTreeNode->m_pLeft, expectedSum, path, currentSum);      if(pTreeNode->m_pRight)            FindPath(pTreeNode->m_pRight, expectedSum, path, currentSum);      // when we finish visiting a node and return to its parent node,      // we should delete this node from the path and       // minus the node's value from the current sum      currentSum -= pTreeNode->m_nValue;      path.pop_back();} 

      细致看代码,你会发现,这样的方法遍历了解空间树,全部的叶子节点都会訪问到,

        假设二叉树是这种呢:

        二元树中和为某一值的全部路径

       依照这样的方法,20的两个孩子都会訪问到,可是,这在做无用功,由于,题目要求的是从根节点到叶子节点的路径和为22,当訪问到20的时候,路径和已是30了(大于22),再訪问20的孩子,路径和也会大于22,这样就没有必要再訪问20的孩子了。

       所以,应该避免这样的无效搜索,在遍历每一个节点的时候,先推断路径和是否大于目标值,假设大于的话,则不要遍历该节点的孩子,而且回溯。

      优化后的代码为:

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;	if(currentSum > expectedSum){  //推断路径和是否会超出目标值,超出则回溯		currentSum -= pTreeNode->m_nValue;		return;	}	path.push_back(pTreeNode->m_nValue);		// if the node is a leaf, and the sum is same as pre-defined,		// the path is what we want. print the path	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 the node is not a leaf, goto its children	if(pTreeNode->m_pLeft)		FindPath(pTreeNode->m_pLeft, expectedSum, path, currentSum);	if(pTreeNode->m_pRight)		FindPath(pTreeNode->m_pRight, expectedSum, path, currentSum);	// when we finish visiting a node and return to its parent node,	// we should delete this node from the path and	// minus the node's value from the current sum	currentSum -= pTreeNode->m_nValue;	path.pop_back();}

        在原来的代码里添加�了例如以下代码:

if(currentSum > expectedSum){  //推断路径和是否会超出目标值,超出则回溯		currentSum -= pTreeNode->m_nValue;		return;	}

        剪去无效的子树,避免无效搜素,提高效率。

參考:

http://zhedahht.blog.163.com/blog/static/254111742007228357325/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118895.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 毕业前写了20万行代码,让我从成为同学眼里的面霸

    毕业前写了20万行代码,让我从成为同学眼里的面霸作者:小傅哥博客:https://bugstack.cn沉淀、分享、成长,让自己和他人都能有所收获!????一、前言20万行代码写完,毕业了找一份工作不是问题!刚一毕业因为找不到工作,就得报名去参加Java培训的大有人在。并不是说参加培训就不好,只不过以你现在这个毕业的时间点参加,就会显得特别匆忙。因为你的压力既来自于培训还需要花家里一笔不小的费用,也有同班同学已经找到一份不错的工作开始赚钱的比对。大学四年其实有足够的时间让你学会编程,也能从一个较长时间的学习中,知道自己适合不适合做程序员。

    2022年6月12日
    21
  • 二进制表示小数「建议收藏」

    二进制表示小数「建议收藏」二进制表示小数二进制表示小数TableofContents1.题目2.方法3.思路1题目给定一个数将其转换为二进制(均用字符串表示),如果这个数的小数部分不能在32个字符之内来精确地表

    2022年8月4日
    5
  • Clover 引导器.配置助手[通俗易懂]

    Clover引导器.配置助手.Yosemite版块.更新贴Beta2.0为了让各位下载更方便本帖不设置回帖可见希望路过的朋友帮顶有需要的朋友顶个帖让更多后来者们看见提取码[编译PKG]py81[编译EFI+boot1h2]8ctu[编译ISO]zq9f首先向Clover开发人员致敬:Slice,withhelpofKabyl,

    2022年4月10日
    36
  • pycharm报错traceback most_cm3d2报错error

    pycharm报错traceback most_cm3d2报错errorPycharm报错Pythonerror:PermissionError:[Errno13]Permissiondenied:在pycharm中读取csv文件时,出现错误PermissionError:[Errno13]Permissiondenied:。看了大部分博客说是因为文件权限问题,或者文件被手动打开,这两个方法都试了试后,无效。解决问题的方法:配置Python编译器时将ScriptPath的路径写到脚本的具体路径,要包含脚本的文件名。如下图。…

    2022年8月26日
    5
  • app软件开发的基本流程_app项目开发流程

    app软件开发的基本流程_app项目开发流程 本文转载自互联网,如有侵权,请联系我及时删除。谢谢。(一)项目启动前  从事产品的工作一年多,但自己一直苦于这样或者那样的困惑,很多人想要从事产品,或者老板自己创业要亲自承担产品一职,但他们对产品这个岗位的认识却不明晰,有的以为是纯粹的画原型,有的是以为做项目管理跟踪项目进度,有的是做竞品分析给老板看。实际上,这些都不是产品经理的核心和重点。在较为成熟的企业,因为产品的壮大和人员的增多,…

    2025年6月26日
    3
  • pytest运行_python缓存机制

    pytest运行_python缓存机制前言pytest运行完用例之后会生成一个.pytest_cache的缓存文件夹,用于记录用例的ids和上一次失败的用例。方便我们在运行用例的时候加上–lf和–ff参数,快速运行上一

    2022年7月31日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号