【LRD,DLR】BST的后续遍历序列,二叉树中和为某一值的路径

版权声明:本文为博主原创学习笔记,如需转载请注明来源。 https://blog.csdn.net/SHU15121856/article/details/82585796

D是Degree,后续遍历就是LRD,前序遍历就是DLR。

面试题33:BST的后序遍历序列

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。

后序遍历是左右中,而根据BST的特性,这个序列中的数字大小情况是小大中,以最后一个结点根节点为基准,可以判断这一层是不是符合要求,同时也划分出了左右子树,再分别对左右子树做递归地判断。

#include<bits/stdc++.h>
using namespace std;

// 参数:
//        sequence:       后续遍历序列 
//        length:         序列的长度 
// 返回值:
//        这个后序遍历序列能否属于某BST(二叉搜索树) 
bool VerifySquenceOfBST(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;//这时就退出,i点左侧的全部值属于左子树 
    }

    //在二叉搜索树中右子树的结点大于根结点
    int j = i;//从刚刚找到的分界位置 
    for(; j < length - 1; ++ j) {//继续向后检查应当是右子树的部分 
        if(sequence[j] < root)//如果发现比根结点小的值 
            return false;//说明该序列不满足要求,绝不是BST的后续遍历序列 
    }

    //判断左子树是不是二叉搜索树
    bool left = true;
    if(i > 0)//分界点i>0左子树才是真实存在的,即至少有个sequence[0]结点\
        //分界点i正好表示其左侧的结点数,即左子树结点数 
        left = VerifySquenceOfBST(sequence, i);

    //判断右子树是不是二叉搜索树
    bool right = true;
    if(i < length - 1)//分界点i不到达根结点位置,右子树才是真实存在的
        //序列起始点要跳过i个左子树结点,序列长度要减掉1个根节点和i个左子树结点 
        right = VerifySquenceOfBST(sequence + i, length - i - 1); 

    //左右子树都为BST时,在该子树上才能认为是BST 
    return (left && right);
}

//            10
//         /      \
//        6        14
//       /\        /\
//      4  8     12  16
int main() {
    int data[] = {4, 8, 6, 12, 16, 14, 10};
    cout<<boolalpha<<VerifySquenceOfBST(data,sizeof(data)/sizeof(int));
    return 0;
}

面试题34:二叉树中和为某一值的路径

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

DFS遍历这棵二叉树,然后每次走到叶结点就判断一下是否满足条件。可以用前序遍历即中左右来DFS这棵二叉树。

#include<bits/stdc++.h>
#include "../Utilities/BinaryTree.h"
using namespace std;

void FindPath(BinaryTreeNode* pRoot, int expectedSum, std::vector<int>& path, int& currentSum);

// 参数:
//        pRoot:         二叉树根
//        expectedSum:   想检查的路径和
// 输出:
//        找到的路径
void FindPath(BinaryTreeNode* pRoot, int expectedSum) {
    if(pRoot == nullptr)
        return;
    //用vector模拟栈,因为打印路径时需要得到路径上所有结点,stack不方便
    vector<int> path;
    int currentSum = 0;//当前路径上的加和
    FindPath(pRoot, expectedSum, path, currentSum);
}

//递归函数,在二叉子树上,根据当前已检查到的路径和继续检查,直到叶子
void FindPath
(
    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 == nullptr;
    //如果路径上结点的和等于输入的值,并且是叶结点
    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)
        FindPath(pRoot->m_pLeft, expectedSum, path, currentSum);
    if(pRoot->m_pRight != nullptr)
        FindPath(pRoot->m_pRight, expectedSum, path, currentSum);

    //在返回到父结点之前,在路径上删除当前结点
    path.pop_back();//将其弹出(尾出)
    //并在当前路径和中减去这个结点的值
    currentSum -= pRoot->m_nValue;
}

//            10
//         /      \
//        5        12
//       /\        
//      4  7  
int main() {
    BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
    BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
    BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
    BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);

    ConnectTreeNodes(pNode10, pNode5, pNode12);
    ConnectTreeNodes(pNode5, pNode4, pNode7);

    FindPath(pNode10,22);

    DestroyTree(pNode10);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/SHU15121856/article/details/82585796