剑指offer面试题25-二叉树中和韦某一值的路径

来源:互联网 发布:博雅软件怎么用 编辑:程序博客网 时间:2024/05/16 03:36

question:给定一颗二叉树,一个值。我们希望输出和为该值的所有路径。

假设树的结构如下


思路:使用一个基于先序遍历的递归过程来遍历树中每个点一次,每遍历一个点就要获得从根节点到被访问的点的累加和,并保存从根节点到当前点的路径。然后进行判断,

case1如果当前点的左右孩子都为空(叶子节点)并且累加和等于我们期望的和,那么就打印出路径;

case2如果左孩子为空,递归到最孩子;

case3如果右孩子为空,递归到右孩子;

case4如果是叶子并且当前和不等于期望和,网上回退

试下代码:

参数为值传递的代码

#include<vector>#include<iostream>using namespace std;typedef struct BinaryTreeNode{int data;struct BinaryTreeNode *lchild;struct BinaryTreeNode *rchild;}*BinTreeRoot;void createTree1(BinaryTreeNode *&root){root = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));root->data = 8;root->lchild = NULL;root->rchild = NULL;BinaryTreeNode *p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 8;p->lchild = NULL;p->rchild = NULL;root->lchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 7;p->lchild = NULL;p->rchild = NULL;root->rchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 9;p->lchild = NULL;p->rchild = NULL;root->lchild->lchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 2;p->lchild = NULL;p->rchild = NULL;root->lchild->rchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 4;p->lchild = NULL;p->rchild = NULL;root->lchild->rchild->lchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 7;p->lchild = NULL;p->rchild = NULL;root->lchild->rchild->rchild = p;}void findPath(BinaryTreeNode *root, int expectedSum, int curSum, vector<int>path){if (root == NULL)return;curSum += root->data;path.push_back(root->data);if (root->lchild == NULL && root->rchild == NULL && curSum == expectedSum){for (auto iter = path.begin(); iter != path.end();  ++iter){if (iter + 1 == path.end()){cout << *iter << endl;}else{cout << *iter << "->";}}}if (root->lchild != NULL){findPath(root->lchild, expectedSum, curSum, path);}if (root->rchild != NULL){findPath(root->rchild, expectedSum, curSum, path);}//curSum -= root->data;//path.pop_back();}int main(){BinaryTreeNode *root = NULL;createTree1(root);if (root == NULL){cout << "the tree is empty!" << endl;return 0;}int curSum = 0;//存放从根节点到当前节点的路径和int expectedSum;//我们期待的值cin >> expectedSum;vector<int>path;//存放路径findPath(root, expectedSum, curSum, path);return 0;}
注意:在这个代码中存放累加和curSum、路径path的变量都是使用的值传递,而不是引用传递。因为该方法是一个递归的过程,在每一个递归栈中都有一个临时变量curSum和path。如果递归返回到上一层时,本次计算的没有影响。相反,如果使用了引用传递的,需要手动修改数据的值:

参数为引用传递的代码:

#include<vector>#include<iostream>using namespace std;typedef struct BinaryTreeNode{int data;struct BinaryTreeNode *lchild;struct BinaryTreeNode *rchild;}*BinTreeRoot;void createTree1(BinaryTreeNode *&root){root = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));root->data = 8;root->lchild = NULL;root->rchild = NULL;BinaryTreeNode *p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 8;p->lchild = NULL;p->rchild = NULL;root->lchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 7;p->lchild = NULL;p->rchild = NULL;root->rchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 9;p->lchild = NULL;p->rchild = NULL;root->lchild->lchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 2;p->lchild = NULL;p->rchild = NULL;root->lchild->rchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 4;p->lchild = NULL;p->rchild = NULL;root->lchild->rchild->lchild = p;p = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));p->data = 7;p->lchild = NULL;p->rchild = NULL;root->lchild->rchild->rchild = p;}void findPath(BinaryTreeNode *root, int expectedSum, int &curSum, vector<int>&path)//引用传递{if (root == NULL)return;curSum += root->data;path.push_back(root->data);if (root->lchild == NULL && root->rchild == NULL && curSum == expectedSum){for (auto iter = path.begin(); iter != path.end();  ++iter){if (iter + 1 == path.end()){cout << *iter << endl;}else{cout << *iter << "->";}}}if (root->lchild != NULL){findPath(root->lchild, expectedSum, curSum, path);}if (root->rchild != NULL){findPath(root->rchild, expectedSum, curSum, path);}curSum -= root->data;//curSum和path是引用传递,所以如果递归返回到上一层的时候,需要减去本次的累加path.pop_back();}int main(){BinaryTreeNode *root = NULL;createTree1(root);if (root == NULL){cout << "the tree is empty!" << endl;return 0;}int curSum = 0;//存放从根节点到当前节点的路径和int expectedSum;//我们期待的值cin >> expectedSum;vector<int>path;//存放路径findPath(root, expectedSum, curSum, path);return 0;}

过程:假设我们希望输出和为25的所有路径;

设定以下变量:int curSum = 0;//存放当前累加和

                         int expectedSum = 25;//期待和

                         vector<int>path;//用于存放路径

                         BinaryTreeNode *root;//指向树中根节点的指针

(1)首先从根节点出发,curSum = 8,并且不是叶子节点,并且值不为35。


(2)由于是基于先序遍历的,接下来我们访问左孩子,累加和为8+8=16,仍然不是叶子节点。


(3)再访问8的右孩子9,累加和为25,并且是叶子节点。此时打印出路径


路径为8->8->9

(4)使用一个递归的过程,然后向上回退到节点8,并且访问8的右孩子2


(5)访问2的左孩子4,此时累加和为22.


(6)当前访问到的点4是一个叶子节点,并且累加和为22,不是我们所期待的,所以向上回退到2,并且访问2的右孩子7,此时7是叶子节点。并且和为25,所以满足要求,打印出路径


路径为:8->8->2->7

阅读全文
0 0
原创粉丝点击