您的位置:首页 > Web前端

剑指Offer-25-二叉树中和为某一值的路径

2015-11-16 11:19 399 查看
题目:

输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始一直到叶结点所经过的结点形成一条路径。

思路:

使用辅助栈保存目前遍历所得路径,使用前序遍历的方式遍历二叉树。

1.如果目前路径所有结点值的和等于期望值,并且该结点为叶节点,打印该辅助栈保存的路径。

2.如果目前路径所有结点值的和小于期望值,递归调用函数,传入该结点的子结点。

3.如果目前路径所有结点值的和大于期望值,或该结点非叶节点等于期望值,递归结束。

4.(1,2,3) 在返回到父结点之前,在路径上删除当前结点。

#include <iostream>
#include <stack>
using namespace std;

struct BinaryTreeNode {
int m_nValue;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};

void FindPath(BinaryTreeNode *root, int expectedSum, int nowSum,
std::stack<BinaryTreeNode *>& path);
void print(std::stack<BinaryTreeNode *> path);

void FindPath(BinaryTreeNode *root, int sum) {
if (root == NULL)
return;
std::stack<BinaryTreeNode *> path;
FindPath(root, sum, 0, path);
}

/*
*查询路径
*/
void FindPath(BinaryTreeNode *root, int expectedSum, int nowSum,
std::stack<BinaryTreeNode *>& path) {
if (root == NULL)
return;
nowSum += root->m_nValue;
path.push(root);
// 如果是叶结点,并且路径上结点的和等于输入的值
// 打印出这条路径
if (nowSum == expectedSum) {
if (root->m_pLeft == NULL && root->m_pRight == NULL) {
//打印路径
print(path);
cout<<endl;
}
}
//如果当前路径上结点的和小于输入的值
//并且结点不是叶结点,则遍历它的子结点
if(nowSum < expectedSum) {
if (root->m_pLeft != NULL)
FindPath(root->m_pLeft, expectedSum, nowSum, path);
if (root->m_pRight != NULL)
FindPath(root->m_pRight, expectedSum, nowSum, path);
}
// 在返回到父结点之前,在路径上删除当前结点
path.pop();
}

/*
* 打印路径
*/
void print(std::stack<BinaryTreeNode *> path){
if(!path.empty()) {
BinaryTreeNode *node = path.top();
path.pop();
print(path);
cout<<node->m_nValue<<" ";
}
}

//使用前序遍历和中序遍历的结果构建二叉树
//a前序遍历序列,b中序遍历序列
BinaryTreeNode* build(int*a,int la,int ra,int* b,int lb,int rb) {
if(la > ra)
return NULL;
//用于统计左子树结点个数
int len = 0;
// 在中序遍历中找到根结点的值
for(int i=lb;i<=rb;i++) {
if(a[la] == b[i]) {
break;
}
len++;
}
//创建结点 前序遍历序列的第一个数字是根结点的值
BinaryTreeNode *root = new BinaryTreeNode();
root->m_nValue = a[la];//即 b[lb+len]
//构造左子树,左子树结点个数个数为len
root->m_pLeft = build(a,la+1,la+len,b,lb,lb+len-1);
//构造右子树, 右子树结点个数为rb-lb-len
root->m_pRight = build(a,ra-rb+lb+len+1,ra,b,lb+len+1,rb);
return root;
}

// 普通二叉树
//              1
//           /     \
//          2       3
//         /       / \
//        4       5   6
//         \         /
//          7       8
void Test1()
{
const int length = 8;
int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8};
int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6};
BinaryTreeNode *root = build(preorder,0,length-1,inorder,0,length-1);
FindPath(root,9);
}

// 所有结点都没有右子结点
//            1
//           /
//          2
//         /
//        3
//       /
//      4
//     /
//    5
void Test2()
{
const int length = 5;
int preorder[length] = {1, 2, 3, 4, 5};
int inorder[length] = {5, 4, 3, 2, 1};
BinaryTreeNode *root = build(preorder,0,length-1,inorder,0,length-1);
FindPath(root,15);
}

// 所有结点都没有左子结点
//            1
//             \
//              2
//               \
//                3
//                 \
//                  4
//                   \
//                    5
void Test3()
{
const int length = 5;
int preorder[length] = {1, 2, 3, 4, 5};
int inorder[length] = {1, 2, 3, 4, 5};
BinaryTreeNode *root = build(preorder,0,length-1,inorder,0,length-1);
FindPath(root,15);
}

// 树中只有一个结点
void Test4()
{
const int length = 1;
int preorder[length] = {1};
int inorder[length] = {1};
BinaryTreeNode *root = build(preorder,0,length-1,inorder,0,length-1);
FindPath(root,1);
}

int main() {
Test1();
Test2();
Test3();
Test4();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: