24 二叉搜索树的后序遍历序列
【1】题目
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
【2】思路
(1)后序遍历最后的一个节点为根节点;
(2)小于最后的一个节点的为左子树,大于最后一个节点为右子树;
(3)判断左子树和右子树是否为二叉搜索树
(4)二者都为二叉搜索树则结果为后序遍历的结果,反之不是
面试题25:二叉树中和为某一值的路径
【1】题目
题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径
【2】思路
(1)从根节点开始向下遍历,并计算由根节点到当前节点的累加值;
(2)如果当前节点为叶子节点,则计算根节点到当前节点的累计值;
(3)若值等于所要求的值,则显示打印该路径,如果不是,则减去当前节点的值,返回上一节点;
(4)继续遍历右节点,并计算累计的和,并判断是否为叶子节点,如果是叶子节点,则比较值。
【3】代码
#pragma once
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include<vector>
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
class BrinarTree
{
public:
BrinarTree();
~BrinarTree();
//判断输入数据是否为后序遍历的结果
bool VerifSquenceofBST(int sequence[], int lengrh);
//二叉树某一路径的和为定值
void FindPath(BinaryTreeNode * pRoot, int expectedSum);
void FindallPath(BinaryTreeNode * pRoot, int expectedSum, std::vector<int> & path, int currentSum);
};
#endif // !BINARYTREE_H
BrinarTree::BrinarTree()
{
}
BrinarTree::~BrinarTree()
{
}
#include"BrinarTree.h"
#include<vector>
using namespace std;
//后续遍历的顺序是左右中
bool BrinarTree::VerifSquenceofBST(int sequence[], int length)
{
//输入数据为空
if (sequence==nullptr||length<=0)
{
return false;
}
//输入数据的最后一个值为根节点
int root = sequence[length - 1];
//根据根节点切分左右子树
//---------------------------------------------------------------------------
//二叉树中搜索左子树,左子树的元素均小于根节点.
//若大于根节点,则左子树遍历完了或者不是后序遍历的结果
int i = 0;
for (; i < length-1; i++)
{
if (sequence[i]>root)
{
break;
}
}
//左子树遍历完了之后,遍历右子树是否合乎要求
//右子树的节点值均要大于根节点
int j = i;
for (; j < length; j++)
{
//如果右子树中存在节点的值小于根节点,则该序列不是后序遍历的结果
if (sequence[j]< root)
{
return false;
}
}
//---------------------------------------------------------------------------
//-------------------------判断左右子树是否为二叉搜索树-----------------------------------
//判断左子树是否为二叉搜索树
bool left = true;
if (i>0)
{
left = VerifSquenceofBST(sequence, i);
}
//判断右子树是否为二叉搜索树
bool right = true;
if (i<length-1)
{
right = VerifSquenceofBST(sequence + i, length - i - 1);
}
return (left&&right);
}
void BrinarTree::FindallPath(BinaryTreeNode * pRoot, int expectedSum, vector<int> & path, int currentSum)
{
//计算累计到当前节点时,累计的和值为多少。将当前根节点存放到路径中
currentSum += pRoot->m_nValue;
path.push_back(pRoot->m_nValue);
//判断当前节点是否为叶节点
bool isLeaf = pRoot->m_pLeft == nullptr && pRoot->m_pRight == NULL;
//当前节点是叶子节点且路径和为设置的路径和,则打印显示
if (currentSum==expectedSum && isLeaf)
{
printf("A path is found:");
//迭代器打印显示
vector<int>::iterator iter = path.begin();
for (; iter!=path.end(); iter++)
{
printf("%d\t", *iter);
}
printf("\n");
}
//如果不是叶节点,继续递归调用函数,计算路径和
if (pRoot->m_pLeft!=nullptr)
{
FindallPath(pRoot->m_pLeft, expectedSum, path, currentSum);
}
if (pRoot->m_pRight != nullptr)
{
FindallPath(pRoot->m_pRight, expectedSum, path, currentSum);
}
//默认此节点为叶节点,则需要将去当前叶节点的值,然后在返回上一层的节点
currentSum -= pRoot->m_nValue;
path.pop_back();
}
//遍历路径的和是否为某一定值
void BrinarTree::FindPath(BinaryTreeNode * pRoot, int expectedSum)
{
//根节点为空
if (pRoot==nullptr)
{
return;
}
//节点不为空
vector<int> path;
int currenSum = 0;
FindallPath(pRoot,expectedSum,path,currenSum);
}