careercup-树与图 4.9
4.9 给定一颗二叉树,其中每个结点都含有一个数值。设计一个算法,打印结点数值总和等于某个给定值的所有路径。注意,路径不一定非得从二叉树的根节点或叶子节点开始或结束。
类似于leetcode:Path Sum II
C++实现代码:(使用了双重的递归)对于不含有parent指针域时。
#include<iostream>
#include<new>
#include<vector>
using namespace std; //Definition for binary tree
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
}; class Solution
{
public:
vector<vector<int> > path;
vector<vector<int> > pathSum(TreeNode *root, int sum)
{
vector<int> tmp;
hasPathSum(root,sum,tmp);
//改变开始的节点,不一定要从根结点开始,遍历从每一个节点开始
if(root->left)
pathSum(root->left,sum);
if(root->right)
pathSum(root->right,sum);
return path;
}
void hasPathSum(TreeNode *root, int sum,vector<int> tmp)
{
if(root==NULL)
return;
tmp.push_back(root->val);
//改变结束的地方,不一定要到叶子节点
if((sum-root->val)==)
{
path.push_back(tmp);
}
if(root->left)
hasPathSum(root->left,sum-root->val,tmp);
if(root->right)
hasPathSum(root->right,sum-root->val,tmp);
}
void createTree(TreeNode *&root)
{
int i;
cin>>i;
if(i!=)
{
root=new TreeNode(i);
if(root==NULL)
return;
createTree(root->left);
createTree(root->right);
}
}
};
int main()
{
Solution s;
TreeNode *root;
s.createTree(root);
vector<vector<int> > path=s.pathSum(root,);
for(auto a:path)
{
for(auto v:a)
cout<<v<<" ";
cout<<endl;
}
}
方法二:如果结点中包含指向父亲结点的指针,那么,只需要去遍历这棵二叉树, 然后从每个结点开始,不断地去累加上它父亲结点的值直到父亲结点为空(这个具有唯一性, 因为每个结点都只有一个父亲结点。也正因为这个唯一性, 可以不另外开额外的空间来保存路径),如果等于给定的值sum,则打印输出。
实现的方法:
void find_sum(Node* head, int sum){
if(head == NULL) return;
Node *no = head;
int tmp = ;
for(int i=; no!=NULL; ++i){
tmp += no->key;
if(tmp == sum)
print(head, i);
no = no->parent;
}
find_sum(head->lchild, sum);
find_sum(head->rchild, sum);
}
打印输出时,只需要提供当前结点的指针,及累加的层数即可。然后从当前结点开始, 不断保存其父亲结点的值(包含当前结点)直到达到累加层数,然后逆序输出即可。
代码如下:
void print(Node* head, int level){
vector<int> v;
for(int i=; i<level; ++i){
v.push_back(head->key);
head = head->parent;
}
while(!v.empty()){
cout<<v.back()<<" ";
v.pop_back();
}
cout<<endl;
}
方法三:如果结点中不包含指向父亲结点的指针,则在二叉树从上向下查找路径的过程中, 需要为每一次的路径保存中间结果,累加求和仍然是从下至上的,对应到保存路径的数组, 即是从数组的后面开始累加的,这样能保证遍历到每一条路径。
代码如下:
void print2(vector<int> v, int level){
for(int i=level; i<v.size(); ++i)
cout<<v.at(i)<<" ";
cout<<endl;
}
void find_sum2(Node* head, int sum, vector<int> v, int level){
if(head == NULL) return;
v.push_back(head->key);
int tmp = ;
for(int i=level; i>-; --i){
tmp += v.at(i);
if(tmp == sum)
print2(v, i);
}
vector<int> v1(v), v2(v);
find_sum2(head->lchild, sum, v1, level+);
find_sum2(head->rchild, sum, v2, level+);
}
方法二 完整代码:
#include<iostream>
#include<new>
#include<map>
#include<vector>
using namespace std; struct BinarySearchTree
{
int elem;
BinarySearchTree *parent;
BinarySearchTree *left;
BinarySearchTree *right;
BinarySearchTree(int x):elem(x),parent(NULL),left(NULL),right(NULL) {}
}; void insert(BinarySearchTree *&root,int z)
{
BinarySearchTree *y=new BinarySearchTree(z);
if(root==NULL)
{
root=y;
return;
}
else if(root->left==NULL&&z<root->elem)
{
root->left=y;
y->parent=root;
return;
}
else if(root->right==NULL&&z>root->elem)
{
root->right=y;
y->parent=root;
return;
}
if(z<root->elem)
insert(root->left,z);
else
insert(root->right,z);
} void createBST(BinarySearchTree *&root)
{
int arr[]= {,,,,,,,,,};
for(auto a:arr)
insert(root,a);
} //使用level的原因就是因为,不一定要到根,只有根的父节点为NULL
void print(BinarySearchTree *head,int level)
{
vector<int> vec;
for(int i=;i<level;++i)
{
vec.push_back(head->elem);
head=head->parent;
}
while(!vec.empty())
{
cout<<vec.back()<<" ";
vec.pop_back();
}
cout<<endl;
}
//root选择的是当前结束的节点,也就是从下往上开始最下面的节点,而node是往上找到的刚好满足的最后一个结点,root是在不断加深的
void find_sum(BinarySearchTree *root,int sum)
{
if(root==NULL)
return;
BinarySearchTree *node=root;
int tmp=;
for(int i=;node!=NULL;++i)
{
tmp+=node->elem;
if(tmp==sum)
print(root,i);
node=node->parent;
}
find_sum(root->left,sum);
find_sum(root->right,sum);
}
int main()
{
BinarySearchTree *root=NULL;
createBST(root);
cout<<"find sum is: "<<endl;
find_sum(root,);
return ;
}
方法三 完整代码:
#include<iostream>
#include<new>
#include<map>
#include<vector>
using namespace std; struct BinarySearchTree
{
int elem;
BinarySearchTree *parent;
BinarySearchTree *left;
BinarySearchTree *right;
BinarySearchTree(int x):elem(x),parent(NULL),left(NULL),right(NULL) {}
}; void insert(BinarySearchTree *&root,int z)
{
BinarySearchTree *y=new BinarySearchTree(z);
if(root==NULL)
{
root=y;
return;
}
else if(root->left==NULL&&z<root->elem)
{
root->left=y;
y->parent=root;
return;
}
else if(root->right==NULL&&z>root->elem)
{
root->right=y;
y->parent=root;
return;
}
if(z<root->elem)
insert(root->left,z);
else
insert(root->right,z);
} void createBST(BinarySearchTree *&root)
{
int arr[]= {,,,,,,,,,};
for(auto a:arr)
insert(root,a);
} //使用level记录选择v中的从哪个下标开始相加
void print(vector<int> v,int level)
{
for(int i=level;i<v.size();++i)
cout<<v[i]<<" ";
cout<<endl;
}
//root开始,将当前层的值加入v中
void find_sum(BinarySearchTree *root,int sum,vector<int> v,int level)
{
if(root==NULL)
return;
v.push_back(root->elem);
int tmp=;
for(int i=level;i>-;--i)
{
tmp+=v[i];
if(tmp==sum)
print(v,i);
}
//每一层将当前层的结点的值放入v中,由于不是传递的引用,所以同一层放入v中的值不会影响,从root结点开始保存每一层的
find_sum(root->left,sum,v,level+);
find_sum(root->right,sum,v,level+);
}
int main()
{
BinarySearchTree *root=NULL;
createBST(root);
vector<int> v;
cout<<"find sum is: "<<endl;
find_sum(root,,v,);
return ;
}

careercup-树与图 4.9的更多相关文章
- SqlServer-无限递归树状图结构设计和查询
在现实生活中,公司的部门设计会涉及到很多子部门,然后子部门下面又存在子部门,形成类似判断的树状结构,比如说评论楼中楼的评论树状图,职位管理的树状图结构等等,实现类似的树状图数据结构是在开发中经常出现的 ...
- Android开源图表之树状图和饼状图的官方示例的整理
最近由于工作需要,所以就在github上搜了下关于chart的三方框架 官方地址https://github.com/PhilJay/MPAndroidChart 由于工作需要我这里整理了一份Ecli ...
- D3树状图给指定特性的边特别显示颜色
D3作为前端图形显示的利器,功能之强,对底层技术细节要求相对比较多. 有一点,就是要理解其基本的数据和节点的匹配规则架构,即enter,update和exit原理,我前面的D3基础篇中有介绍过,不明白 ...
- D3树状图异步按需加载数据
D3.js这个绘图工具,功能强大不必多说,完全一个Data Driven Document的绘图工具,用户可以按照自己的数据以及希望实现的图形,随心所欲的绘图. 图形绘制,D3默认采用的是异步加载,但 ...
- [整理] ES5 词法约定文档树状图
将ES5 词法说明整理为了树状图,方便查阅,请自行点开小图看大图:
- bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]
4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...
- vue 树状图数据的循环 递归循环
在main.js中注册一个子组件 在父组件中引用 树状图的数据格式 绑定一个数据传入子组件,子组件props接收数据 子组件中循环调用组件,就实现了递归循环
- ztree 文件夹类型的 树状图
未套程序的源代码: 链接:http://pan.baidu.com/s/1nuHbxhf 密码:4aw2 已套程序的源代码: css样式: /*发布邮件 选择领导弹窗*/ .xuandao{ disp ...
- visio画等分树状图
一 树状图形状 Search里搜索Tree,找到Double Tree或者Multi Tree的形状 二 分出更多branch 按住主干上的黄色小方块,拖出更多分支. 三 等分分支 将每个分支和对应的 ...
- ArcGIS教程:树状图
摘要 构造可显示特征文件里连续合并类之间的属性距离的树示意图(树状图). 使用方法 · 输入特征文件必须採用预定的特征文件格式. 特征文件可使用 Iso 聚类或创建特征工具来创建.该文件必须至少包括两 ...
随机推荐
- NGUI所见即所得之UIAtlasMaker , UIAtlas (2)
本文的重点就是要将NGUI把多张图片打成一个图集(Atlas)的原理和过程研究下,学习下Unity提供的api和NGUI写的功能以及设计思想. (原文链接) 其它链接:NGUI所见即所得之UIRoot ...
- 告别山寨数据线:USB Type-C加密认证出炉
从去年苹果发布的MacBook首次采用USB Type-C接口开始,这一标准逐渐成为主流,许多旗舰手机慢慢地采用了这种接口.今日,非盈利机构USB开发者论坛(USB-IF)宣布了USB Type-C认 ...
- 如何才能学到Qt的精髓——信号槽之间的无关性,提供了绝佳的对象间通讯方式,QT的GUI全是自己的一套,并且完全开源,提供了一个绝好机会窥视gui具体实现
姚冬,中老年程序员 叶韵.KY Xu.赵奋强 等人赞同 被邀请了很久了,一直在思考,今天终于下决心开始写回答. 这个问题的确是够大的,Qt的代码规模在整个开源世界里也是名列前茅的,这么大的项目其中的精 ...
- function(a)
问题: 问个初级的问题int a = 8;function(a);这里在function中的a值是引用a内存中的数据,还是新开辟内存后将a的值赋值到新内存供函数调用. 回答: int a = 8; ...
- linux进程间通信方式
(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信. (2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具 ...
- Styles and Themens(5)样式文件Style.xml中各元素的含义
Style Resource See also Styles and Themes A style resource defines the format and look for a UI. A s ...
- Application.EnableVisualStyles();
Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application ...
- 【HDOJ】1540 Tunnel Warfare
还不错的一道线段树区间合并.挺巧妙的用法. /* 1540 */ #include <iostream> #include <string> #include <map& ...
- Windows系统性能提升方法
看前提醒:在确认没有病毒和流氓软件的前提下,建议优化电脑:以下操作已经在Win7上试验,Win7以上的园友自己试验,自己感受,对电脑无害,但操作时请务必小心 设置虚拟内存 虚拟内存最小值物理内存1.5 ...
- (Deep) Neural Networks (Deep Learning) , NLP and Text Mining
(Deep) Neural Networks (Deep Learning) , NLP and Text Mining 最近翻了一下关于Deep Learning 或者 普通的Neural Netw ...