博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二元树中和为某一值的全部路径
阅读量:6669 次
发布时间:2019-06-25

本文共 3333 字,大约阅读时间需要 11 分钟。

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

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

     比如输入整数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
& 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
::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
& 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
::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;	}
        剪去无效的子树,避免无效搜素,提高效率。

參考:

你可能感兴趣的文章
AutoMapper(二)
查看>>
OpenGL ES 3.0之VertexAttributes,Vertex Arrays,and Buffer Objects(九)
查看>>
as3随机数
查看>>
四种方案解决ScrollView嵌套ListView问题
查看>>
[IIS] IIS Framework "aspnet_regiis.exe" 注册
查看>>
乘法逆元模板
查看>>
Oracle更改redo log大小 or 增加redo log组
查看>>
matplotlib油漆基础
查看>>
SAP NUMBER RANGE维护配置object FBN1 Deletion only possible if status is initial
查看>>
为什么要优化你的代码?
查看>>
各类小公式
查看>>
【杂文】2015年度总结
查看>>
25个可遇不可求的jQuery插件
查看>>
【LeetCode】【Python题解】Single Number &amp; Maximum Depth of Binary Tree
查看>>
uiautomatorviewer 可以查看到android中的web 元素信息
查看>>
当Scheduler拿不到url的 时候,不能立即退出
查看>>
[每天一个知识点]34-职业生涯-用得着和用不着的知识
查看>>
操作系统 进程与线程 图解浅析
查看>>
coursera课程Text Retrieval and Search Engines之Week 2 Overview
查看>>
BZOJ 2768: [JLOI2010]冠军调查 最小割
查看>>