【程序猿笔试面试解题指南】在二元树中找出和为某一值的所有路径

题目:

输入一个整数和一棵二元树。

从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。
打印出和与输入整数相等的所有路径。
例如输入整数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

};

--------------------------------------------------------------------------------------------------------------------------------------------------

解题:

首先,我们应该意识到:这是一个搜索或者叫遍历的题目。

一个二叉树的路径数=叶子结点的数目。假如我们在每个结点上再定义一个数据,表示从root到它距离目标和的差距的话:



我们遍历整棵二叉树,当碰到叶子结点且距离为0时,将这条路径打印出来,遍历完成后所有的目标路径也就打印出来了。

下面,我们知道对树的遍历有深度广度两种,使用何种方式其实都能达到目的。可是,由于我们需要打印出路径,而对于BFS你没发很好的回溯出父结点,所以DFS才是我们需要的。

我们也都知道:DFS其实是利用栈结构去实现的(递归调用也是),我们正好使用一个栈去存储到达当前结点的路径。由于在满足情况下需要打印出路径,所以使用vector来模拟栈更利于遍历路径。

下面我们定义解决问题的函数findPath:

void findPath(BinaryTreeNode* root,vector<int> &path,int expectedNum)

这个函数形参为:

root :表示目前到达的结点。

path:存储到达目前结点root的路径。

expectedNum:表示距目标和的差距。


findPath的模拟调用如下:


我们应当注意的是:在回溯时要将push进栈的元素pop出来。

代码:

#include <iostream>
#include <vector>
using namespace std;
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
};
bool isLeaf(BinaryTreeNode* p)
{
    if((p->m_pLeft==NULL)&&(p->m_pRight==NULL))
        return true;
    return false;
}
void findPath(BinaryTreeNode* root,vector<int> &path,int expectedNum)
{
//    cout<<root->m_nValue<<" "<<expectedNum<<endl;
    if(isLeaf(root))
    {
        if(expectedNum-root->m_nValue==0)//expected!
        {
            for(unsigned int i=0;i<path.size();i++)
                cout<<path[i]<<" ";
            cout<<root->m_nValue<<endl;
        }
    }
    else
    {
        if(expectedNum-root->m_nValue>0)
        {
            path.push_back(root->m_nValue);
            if(root->m_pLeft)
                findPath(root->m_pLeft,path,expectedNum-root->m_nValue);
            if(root->m_pRight)
                findPath(root->m_pRight,path,expectedNum-root->m_nValue);
            path.pop_back();
        }
    }
}
//注意main中构建的树是例中的。
int main()
{
    BinaryTreeNode f4={4,NULL,NULL};
    BinaryTreeNode s7={7,NULL,NULL};
    BinaryTreeNode f5={5,&f4,&s7};
    BinaryTreeNode t12={12,NULL,NULL};
    BinaryTreeNode t10={10,&f5,&t12};
    int target=22;
    vector<int> path;
    findPath(&t10,path,target);
    return 0;
}



最后,免责说明:

本人对文章的准确性专业性权威性不负任何责任,望各位睁大眼睛自己甄别,如有错误或更好的见解请在评论中指出,谢谢!




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值