博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
程序员面试题100题第04题——在二元树中找出和为某一值的所有路径
阅读量:5759 次
发布时间:2019-06-18

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

题目:

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

分析:

当访问到某一结点时,把该结点添加到路径上,并累加当前结点的值。如果当前结点为叶结点并且当前路径的和刚好等于输入的整数,则当前的路径符合要求,我们把它打印出来。如果当前结点不是叶结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到父结点。因此我们在函数退出之前要在路径上删除当前结点并减去当前结点的值,以确保返回父结点时路径刚好是根结点到父结点的路径。我们不难看出保存路径的数据结构实际上是一个栈结构,因为路径要与递归调用状态一致,而递归调用本质就是一个压栈和出栈的过程。

参考代码:

方法一:(递归)

void FindPath(TreeNode* const pRoot, int exceptSum,int curSum, std::vector
path){ TreeNode* p =pRoot; if(p==NULL) return ; curSum +=p->data; path.push_back(p); if((curSum==exceptSum) && (p->leftChild==NULL && p->rightChild==NULL)) { std::vector
::iterator iter=path.begin(); for( ; iter!=path.end(); iter++) { cout << (*iter)->data << "\t"; } cout <
leftChild) FindPath(p->leftChild,exceptSum,curSum,path); if(p->rightChild) FindPath(p->rightChild,exceptSum,curSum,path); curSum -=p->data; path.pop_back();}

方法二:(迭代)

请考虑

 

方法三:(递归得到所有路径,分别求出每条路径的和值)

递归打印二叉树所有路径:

void FindAllPath(TreeNode* const pRoot, std::vector
path)//递归打印所有路径{ TreeNode* p =pRoot; if(p==NULL) return ; path.push_back(p); if( p->leftChild==NULL && p->rightChild==NULL)//isLeaf then print path { std::vector
::iterator iter=path.begin(); for( ; iter!=path.end(); iter++) { cout << (*iter)->data << "\t"; } } if(p->leftChild) FindAllPath(p->leftChild,path); if(p->rightChild) FindAllPath(p->rightChild,path);}

那么通过对所有路径中的每一条和值得到:

void FindPath(TreeNode* const pRoot, std::vector
path,int ExceptSum){ TreeNode* p =pRoot; int sum=0; if(p==NULL) return ; path.push_back(p); if( p->leftChild==NULL && p->rightChild==NULL) { std::vector
::iterator iter=path.begin(); for( ; iter!=path.end(); iter++) { sum += (*iter)->data; } if(sum==ExceptSum) { iter=path.begin(); for( ; iter!=path.end(); iter++) { cout << (*iter)->data << "\t"; } cout <
leftChild) FindPath(p->leftChild,path,ExceptSum); if(p->rightChild) FindPath(p->rightChild,path,ExceptSum);}

 方法四:(非递归得到所有路径,分别求出每条路径的和值)

 非递归打印所有路径:转自:

void FindAllPath2(TreeNode* const pRoot,std::vector
path){ if(pRoot==NULL) return ; enum Tag{goLeft, goRight, goBack }; vector
vec_flag; TreeNode* p=pRoot; path.push_back(p); vec_flag.push_back(goLeft); while( !path.empty()) { TreeNode *curTreeNode = path.back(); Tag curFlag = vec_flag.back(); switch(curFlag) { case goLeft: vec_flag.pop_back(); vec_flag.push_back(goRight); if(curTreeNode->leftChild != NULL) { path.push_back(curTreeNode->leftChild); vec_flag.push_back(goLeft); } break; case goRight: vec_flag.pop_back(); vec_flag.push_back(goBack); if(curTreeNode->rightChild != NULL) { path.push_back(curTreeNode->rightChild); vec_flag.push_back(goLeft); } break; case goBack: if(NULL == curTreeNode->leftChild && NULL == curTreeNode->rightChild) { std::vector
::iterator iter=path.begin(); for( ; iter!=path.end(); iter++) { cout << (*iter)->data << "\t"; } cout << endl; } vec_flag.pop_back(); path.pop_back(); break; default: break; }//switch-end }//while-end}

那么通过对所有路径中的每一条和值得到:

代码略;

转载于:https://www.cnblogs.com/zjhnl/archive/2012/10/03/2710795.html

你可能感兴趣的文章
一个简单的接口,被调用并同步给出响应的方法
查看>>
我的友情链接
查看>>
显式锁(第十三章)
查看>>
看linux书籍做的一些重要笔记(2011.07.03更新)
查看>>
CString、Char* ,char [20]、wchar_t、unsigned short转化
查看>>
从案例学RxAndroid开发(上)
查看>>
Redis学习手册(内存优化)
查看>>
浅尝TensorFlow on Kubernetes
查看>>
springboot系列十 Spring-Data-Redis
查看>>
Confluence 6 注册外部小工具
查看>>
excel进行矩阵计算
查看>>
基于Android平台的动态生成控件和动态改变控件位置的方法
查看>>
linux 死机分析
查看>>
BOM
查看>>
iOS: Block的循环引用
查看>>
mysql实战02 | 日志系统:一条SQL更新语句是如何执行的?
查看>>
ECC椭圆曲线详解(有具体实例)
查看>>
Linux常见命令(二)
查看>>
PyCharm切换解释器
查看>>
jmp far ptr s所对应的机器码
查看>>