判断二叉树是否为二叉搜索树

判断一个二叉树是否为二叉搜索树

刚开始我想的很简单,觉得只要递归判断左孩子是否小于根节点 右孩子是否大于根节点就行了

        //二叉搜索树 = 左孩子 < 根结点 && 右孩子  > 根节点
        //下面的写法 错的!!!!错的!!!
        //二叉树的判断应该是左子树的最大值 小于 根节点 右子树的最小值大于根节点 
bool isValidBST(TreeNode *root){
        if(root == NULL){
            return true;
        }

        if(root->left != NULL && root->left->val > root->val){
            return false;
        }

        if(root->right != NULL && root->right->val < root->val){
                return false;
        }

        return isValidBST(root->left) && isValidBST(root->right);   
    }

代码实现:



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

struct TreeNode
{
    int val;
    struct TreeNode *left, *right;
    TreeNode(int data): val(data), left(NULL), right(NULL){
    }
};

class Solution{
    public: 
        TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder){
            return buildTree(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
        }
        TreeNode *buildTree(vector<int> &inorder, int iLeft, int iRight, vector<int> &postorder, int pLeft, int pRight) {
            if(iLeft > iRight || pLeft > pRight){
                return NULL;
            }

            TreeNode *cur = new TreeNode (postorder[pRight]);
            int i = 0;
            for(i = iLeft; i < inorder.size(); ++i){
                if(inorder[i] == cur->val){
                    break;
                }
            }

            cur->left = buildTree(inorder, iLeft, i - 1, postorder, pLeft, pLeft + i - iLeft - 1);
            cur->right = buildTree(inorder, i + 1, iRight, postorder, pLeft + i - iLeft, pRight - 1);

            return cur;
        }
        //前序遍历输出
        void PreorderDisplay(TreeNode *root){
            if(root == NULL){
                return ;
            }
            else
            {
                cout << root->val <<" ";
                PreorderDisplay(root->left); 
                PreorderDisplay(root->right);
            }
        }
        //方法一 
        //根据二叉搜索树的特点: 二叉搜索树的中序遍历是递增的 判断一下就行了
        bool isValidBST1(TreeNode *root){
            if(root == NULL){
                return false;
            } 
            vector<int> res;
            InorderDisplay(root, res);
            cout << endl;
            for(int j = 0; j < res.size(); ++j){
                cout << res[j] << " ";
            }

            for(int i = 1; i < res.size(); ++i){
                if(res[i - 1] > res[i]){
                    return false;
                }
            }
            return true;
        }
        //中序遍历生成序列 
        void InorderDisplay(TreeNode *root, vector<int>& res){
            if(root == NULL){
                return ; 
            }
            else
            {
                InorderDisplay(root->left,res);
                res.push_back(root->val);
                InorderDisplay(root->right,res); 
            }
        } 
        //方法二
        //前序遍历 当前节点的值是左子树的最大值,同时是右子树的最小值
        bool isValidBST2(TreeNode *root){
            if(root == NULL){
                return false; 
            }

            return isBST_preorder(root, INT_MIN, INT_MAX);
        } 
        bool isBST_preorder(TreeNode *root, int minVal, int maxVal){
            if(root == NULL){
                return true;
            }

            if(root->val < minVal || root->val > maxVal){
                return false;
            }

            return isBST_preorder(root->left, minVal, root->val) && isBST_preorder(root->right, root->val, maxVal) ;
        }
};

int main(){

    Solution s;
    vector<int> inorder = {2,3,5,6,7,8};
    vector<int> postorder = {2,5,3,8,7,6};  
    TreeNode *root = s.buildTree(inorder, postorder);
    s.PreorderDisplay(root);

    bool flag = s.isValidBST2(root);
    if(flag){
        cout << "true" << endl;
    }
    else
    {
        cout << "false" << endl;
    }
    system("pause");
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值