4.9 给定一颗二叉树,其中每个结点都含有一个数值。设计一个算法,打印结点数值总和等于某个给定值的所有路径。注意,路径不一定非得从二叉树的根节点或叶子节点开始或结束。

类似于leetcode:Path Sum II

C++实现代码:(使用了双重的递归)对于不含有parent指针域时。

  1. #include<iostream>
  2. #include<new>
  3. #include<vector>
  4. using namespace std;
  5.  
  6. //Definition for binary tree
  7. struct TreeNode
  8. {
  9. int val;
  10. TreeNode *left;
  11. TreeNode *right;
  12. TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  13. };
  14.  
  15. class Solution
  16. {
  17. public:
  18. vector<vector<int> > path;
  19. vector<vector<int> > pathSum(TreeNode *root, int sum)
  20. {
  21. vector<int> tmp;
  22. hasPathSum(root,sum,tmp);
  23. //改变开始的节点,不一定要从根结点开始,遍历从每一个节点开始
  24. if(root->left)
  25. pathSum(root->left,sum);
  26. if(root->right)
  27. pathSum(root->right,sum);
  28. return path;
  29. }
  30. void hasPathSum(TreeNode *root, int sum,vector<int> tmp)
  31. {
  32. if(root==NULL)
  33. return;
  34. tmp.push_back(root->val);
  35. //改变结束的地方,不一定要到叶子节点
  36. if((sum-root->val)==)
  37. {
  38. path.push_back(tmp);
  39. }
  40. if(root->left)
  41. hasPathSum(root->left,sum-root->val,tmp);
  42. if(root->right)
  43. hasPathSum(root->right,sum-root->val,tmp);
  44. }
  45. void createTree(TreeNode *&root)
  46. {
  47. int i;
  48. cin>>i;
  49. if(i!=)
  50. {
  51. root=new TreeNode(i);
  52. if(root==NULL)
  53. return;
  54. createTree(root->left);
  55. createTree(root->right);
  56. }
  57. }
  58. };
  59. int main()
  60. {
  61. Solution s;
  62. TreeNode *root;
  63. s.createTree(root);
  64. vector<vector<int> > path=s.pathSum(root,);
  65. for(auto a:path)
  66. {
  67. for(auto v:a)
  68. cout<<v<<" ";
  69. cout<<endl;
  70. }
  71. }

方法二:如果结点中包含指向父亲结点的指针,那么,只需要去遍历这棵二叉树, 然后从每个结点开始,不断地去累加上它父亲结点的值直到父亲结点为空(这个具有唯一性, 因为每个结点都只有一个父亲结点。也正因为这个唯一性, 可以不另外开额外的空间来保存路径),如果等于给定的值sum,则打印输出。

实现的方法:

  1. void find_sum(Node* head, int sum){
  2. if(head == NULL) return;
  3. Node *no = head;
  4. int tmp = ;
  5. for(int i=; no!=NULL; ++i){
  6. tmp += no->key;
  7. if(tmp == sum)
  8. print(head, i);
  9. no = no->parent;
  10. }
  11. find_sum(head->lchild, sum);
  12. find_sum(head->rchild, sum);
  13. }

打印输出时,只需要提供当前结点的指针,及累加的层数即可。然后从当前结点开始, 不断保存其父亲结点的值(包含当前结点)直到达到累加层数,然后逆序输出即可。

代码如下:

  1. void print(Node* head, int level){
  2. vector<int> v;
  3. for(int i=; i<level; ++i){
  4. v.push_back(head->key);
  5. head = head->parent;
  6. }
  7. while(!v.empty()){
  8. cout<<v.back()<<" ";
  9. v.pop_back();
  10. }
  11. cout<<endl;
  12. }

方法三:如果结点中不包含指向父亲结点的指针,则在二叉树从上向下查找路径的过程中, 需要为每一次的路径保存中间结果,累加求和仍然是从下至上的,对应到保存路径的数组, 即是从数组的后面开始累加的,这样能保证遍历到每一条路径。

代码如下:

  1. void print2(vector<int> v, int level){
  2. for(int i=level; i<v.size(); ++i)
  3. cout<<v.at(i)<<" ";
  4. cout<<endl;
  5. }
  6. void find_sum2(Node* head, int sum, vector<int> v, int level){
  7. if(head == NULL) return;
  8. v.push_back(head->key);
  9. int tmp = ;
  10. for(int i=level; i>-; --i){
  11. tmp += v.at(i);
  12. if(tmp == sum)
  13. print2(v, i);
  14. }
  15. vector<int> v1(v), v2(v);
  16. find_sum2(head->lchild, sum, v1, level+);
  17. find_sum2(head->rchild, sum, v2, level+);
  18. }

方法二 完整代码:

  1. #include<iostream>
  2. #include<new>
  3. #include<map>
  4. #include<vector>
  5. using namespace std;
  6.  
  7. struct BinarySearchTree
  8. {
  9. int elem;
  10. BinarySearchTree *parent;
  11. BinarySearchTree *left;
  12. BinarySearchTree *right;
  13. BinarySearchTree(int x):elem(x),parent(NULL),left(NULL),right(NULL) {}
  14. };
  15.  
  16. void insert(BinarySearchTree *&root,int z)
  17. {
  18. BinarySearchTree *y=new BinarySearchTree(z);
  19. if(root==NULL)
  20. {
  21. root=y;
  22. return;
  23. }
  24. else if(root->left==NULL&&z<root->elem)
  25. {
  26. root->left=y;
  27. y->parent=root;
  28. return;
  29. }
  30. else if(root->right==NULL&&z>root->elem)
  31. {
  32. root->right=y;
  33. y->parent=root;
  34. return;
  35. }
  36. if(z<root->elem)
  37. insert(root->left,z);
  38. else
  39. insert(root->right,z);
  40. }
  41.  
  42. void createBST(BinarySearchTree *&root)
  43. {
  44. int arr[]= {,,,,,,,,,};
  45. for(auto a:arr)
  46. insert(root,a);
  47. }
  48.  
  49. //使用level的原因就是因为,不一定要到根,只有根的父节点为NULL
  50. void print(BinarySearchTree *head,int level)
  51. {
  52. vector<int> vec;
  53. for(int i=;i<level;++i)
  54. {
  55. vec.push_back(head->elem);
  56. head=head->parent;
  57. }
  58. while(!vec.empty())
  59. {
  60. cout<<vec.back()<<" ";
  61. vec.pop_back();
  62. }
  63. cout<<endl;
  64. }
  65. //root选择的是当前结束的节点,也就是从下往上开始最下面的节点,而node是往上找到的刚好满足的最后一个结点,root是在不断加深的
  66. void find_sum(BinarySearchTree *root,int sum)
  67. {
  68. if(root==NULL)
  69. return;
  70. BinarySearchTree *node=root;
  71. int tmp=;
  72. for(int i=;node!=NULL;++i)
  73. {
  74. tmp+=node->elem;
  75. if(tmp==sum)
  76. print(root,i);
  77. node=node->parent;
  78. }
  79. find_sum(root->left,sum);
  80. find_sum(root->right,sum);
  81. }
  82. int main()
  83. {
  84. BinarySearchTree *root=NULL;
  85. createBST(root);
  86. cout<<"find sum is: "<<endl;
  87. find_sum(root,);
  88. return ;
  89. }

方法三 完整代码:

  1. #include<iostream>
  2. #include<new>
  3. #include<map>
  4. #include<vector>
  5. using namespace std;
  6.  
  7. struct BinarySearchTree
  8. {
  9. int elem;
  10. BinarySearchTree *parent;
  11. BinarySearchTree *left;
  12. BinarySearchTree *right;
  13. BinarySearchTree(int x):elem(x),parent(NULL),left(NULL),right(NULL) {}
  14. };
  15.  
  16. void insert(BinarySearchTree *&root,int z)
  17. {
  18. BinarySearchTree *y=new BinarySearchTree(z);
  19. if(root==NULL)
  20. {
  21. root=y;
  22. return;
  23. }
  24. else if(root->left==NULL&&z<root->elem)
  25. {
  26. root->left=y;
  27. y->parent=root;
  28. return;
  29. }
  30. else if(root->right==NULL&&z>root->elem)
  31. {
  32. root->right=y;
  33. y->parent=root;
  34. return;
  35. }
  36. if(z<root->elem)
  37. insert(root->left,z);
  38. else
  39. insert(root->right,z);
  40. }
  41.  
  42. void createBST(BinarySearchTree *&root)
  43. {
  44. int arr[]= {,,,,,,,,,};
  45. for(auto a:arr)
  46. insert(root,a);
  47. }
  48.  
  49. //使用level记录选择v中的从哪个下标开始相加
  50. void print(vector<int> v,int level)
  51. {
  52. for(int i=level;i<v.size();++i)
  53. cout<<v[i]<<" ";
  54. cout<<endl;
  55. }
  56. //root开始,将当前层的值加入v中
  57. void find_sum(BinarySearchTree *root,int sum,vector<int> v,int level)
  58. {
  59. if(root==NULL)
  60. return;
  61. v.push_back(root->elem);
  62. int tmp=;
  63. for(int i=level;i>-;--i)
  64. {
  65. tmp+=v[i];
  66. if(tmp==sum)
  67. print(v,i);
  68. }
  69. //每一层将当前层的结点的值放入v中,由于不是传递的引用,所以同一层放入v中的值不会影响,从root结点开始保存每一层的
  70. find_sum(root->left,sum,v,level+);
  71. find_sum(root->right,sum,v,level+);
  72. }
  73. int main()
  74. {
  75. BinarySearchTree *root=NULL;
  76. createBST(root);
  77. vector<int> v;
  78. cout<<"find sum is: "<<endl;
  79. find_sum(root,,v,);
  80. return ;
  81. }

careercup-树与图 4.9的更多相关文章

  1. SqlServer-无限递归树状图结构设计和查询

    在现实生活中,公司的部门设计会涉及到很多子部门,然后子部门下面又存在子部门,形成类似判断的树状结构,比如说评论楼中楼的评论树状图,职位管理的树状图结构等等,实现类似的树状图数据结构是在开发中经常出现的 ...

  2. Android开源图表之树状图和饼状图的官方示例的整理

    最近由于工作需要,所以就在github上搜了下关于chart的三方框架 官方地址https://github.com/PhilJay/MPAndroidChart 由于工作需要我这里整理了一份Ecli ...

  3. D3树状图给指定特性的边特别显示颜色

    D3作为前端图形显示的利器,功能之强,对底层技术细节要求相对比较多. 有一点,就是要理解其基本的数据和节点的匹配规则架构,即enter,update和exit原理,我前面的D3基础篇中有介绍过,不明白 ...

  4. D3树状图异步按需加载数据

    D3.js这个绘图工具,功能强大不必多说,完全一个Data Driven Document的绘图工具,用户可以按照自己的数据以及希望实现的图形,随心所欲的绘图. 图形绘制,D3默认采用的是异步加载,但 ...

  5. [整理] ES5 词法约定文档树状图

    将ES5 词法说明整理为了树状图,方便查阅,请自行点开小图看大图:

  6. bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]

    4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...

  7. vue 树状图数据的循环 递归循环

    在main.js中注册一个子组件 在父组件中引用 树状图的数据格式 绑定一个数据传入子组件,子组件props接收数据 子组件中循环调用组件,就实现了递归循环

  8. ztree 文件夹类型的 树状图

    未套程序的源代码: 链接:http://pan.baidu.com/s/1nuHbxhf 密码:4aw2 已套程序的源代码: css样式: /*发布邮件 选择领导弹窗*/ .xuandao{ disp ...

  9. visio画等分树状图

    一 树状图形状 Search里搜索Tree,找到Double Tree或者Multi Tree的形状 二 分出更多branch 按住主干上的黄色小方块,拖出更多分支. 三 等分分支 将每个分支和对应的 ...

  10. ArcGIS教程:树状图

    摘要 构造可显示特征文件里连续合并类之间的属性距离的树示意图(树状图). 使用方法 · 输入特征文件必须採用预定的特征文件格式. 特征文件可使用 Iso 聚类或创建特征工具来创建.该文件必须至少包括两 ...

随机推荐

  1. SQL Server系统表和常用函数(转)

    sysaltfiles 主数据库 保存数据库的文件 syscharsets 主数据库 字符集与排序顺序sysconfigures 主数据库 配置选项syscurconfigs 主数据库 当前配置选项s ...

  2. poj1160Post Office(DP)

    http://poj.org/problem?id=1160 算水过的吧 四重循环没优化 CZ说爆可过 就爆了 dp[i][j] = min(dp[i][j],dp[i-1][g]-s) 第i个点建在 ...

  3. [Hadoop源码解读](一)MapReduce篇之InputFormat

    平时我们写MapReduce程序的时候,在设置输入格式的时候,总会调用形如job.setInputFormatClass(KeyValueTextInputFormat.class);来保证输入文件按 ...

  4. 【转】国内用户如何加快App Store的访问速度

    原文网址:http://www.app111.com/doc/100024206_1.html 作为国内互联网用户是比较可怜的,除了国外四大顶尖互联网服务不能访问外,就是App Store用得也比较痛 ...

  5. iframe 处理

    import java.io.File; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org ...

  6. [codevs1287]矩阵乘法

    题目描述 Description 小明最近在为线性代数而头疼,线性代数确实很抽象(也很无聊),可惜他的老师正在讲这矩阵乘法这一段内容.当然,小明上课打瞌睡也没问题,但线性代数的习题可是很可怕的.小明希 ...

  7. jdk 中Runtime之单例模式 学习

    这段代码是我从源码中截取的,大家很容易看到currentRuntime是一个静态变量,getRunTime对应的就是getInstacne.不是说这种方法不好吗? public class Runti ...

  8. Zookeeper系列(二)特征及应用场景

    zookeeper类似一个分布式的文件系统,每个节点可以有和它自身或它的子节点相关联的数据,此外指向节点的路劲必须使用绝对路径(不能使用相对路劲):   Znode 对应目录树中的的一个节点,并拥有一 ...

  9. 小波变换和motion信号处理(一)(转)

    写的太好,不得不转:http://www.kunli.info/2011/02/15/fourier-wavelet-motion-signal-1/ 这是<小波变换和motion信号处理> ...

  10. CodeForces 540D--Bad Luck Island(概率DP)

    貌似竟然是我的第一道概率DP.. 手机码代码真不舒服.... /************************************************ Memory: 67248 KB Ti ...