美文网首页
如何判断一颗二叉树是二叉搜索树(BSTree)

如何判断一颗二叉树是二叉搜索树(BSTree)

作者: Magic11 | 来源:发表于2018-03-11 11:42 被阅读0次

    对于如下一颗树,如何判断它是否符合搜索二叉树


    image.png

    首先,要明白搜索二叉树的特点:
    1,根节点的所有左节点的值小于根节点,根节点的所有右节点的值大于根节点;
    2,所有左子树、右子树分别是一颗搜索二叉树。
    根据以上特点,我们可以得出这样一个结论:对搜索二叉树
    进行中序遍历,遍历后得到的序列一定是有序的。利用对二叉树的中序遍历,可以有如下三种方法判断一颗二叉树是否是搜索二叉树。
    这里先定义一下二叉树的节点的结构:

    typedef struct Node {
        int value;
        struct Node *pLeftChild;
        struct Node *pRightChild;
    
    public:
        Node(const int &value) {
            this->value = value;
            pLeftChild = NULL;
            pRightChild = NULL;
        }
    } *PNode;
    

    方法一:通过对二叉树中序遍历,并将遍历后的序列保存到一个数组中,通过判断数组是否有序,从而得出该二叉树是否是搜索二叉树,代码如下:

    void inOrder(PNode node, vector<int>& vec) {
    
        if (node == NULL) {
            return;
        }
    
        if (node->pLeftChild != NULL) {
            inOrder(node->pLeftChild, vec);
        }
    
        cout << "push back into vector: value = " <<node->value<< endl;
        vec.push_back(node->value);
    
        if (node->pRightChild != NULL) {
            inOrder(node->pRightChild, vec);
        }
    }
    

    方法二:这个方法是在方法一的基础之上,方法一是将遍历的序列保存到一个数组中,那么是否可以不保存这样一个数组呢,我们知道,判断是一个数组是否有序,是通过对比数组中前后两个相邻的元素的大小,所以方法的思路是通过一个变量记录上一个访问的节点的值,通过将该值与当前要访问的节点的值进行对比,从而判断是否是二叉树。代码如下:

    bool inOrder2(PNode node, int& lastValue) {
        if (node == NULL) {
            return true;
        }
    
        if (node->pLeftChild != NULL) {
            if (!inOrder2(node->pLeftChild, lastValue)) {
                return false;
            }
        }
        
        cout << "lastValue: " << lastValue << "   curValue: " << node->value << endl;
    
        if (lastValue > node->value) {
            return false;
        }
    
        lastValue = node->value;
    
        if (node->pRightChild != NULL) {
            if (!inOrder2(node->pRightChild, lastValue)) {
    
                return false;
            }
        }
    }
    

    方法三:该方法也是是基于中序遍历实现,由于每个节点的值必定满足一定的范围,通过对每个节点设置合理的范围值来判断是否是二叉搜索书,代码如下:

    bool inOrder3(PNode node, int& minValue, int& maxValue) {
        if (node == NULL) {
            return true;
        }
    
    
        if (node->pLeftChild != NULL) {
            if (!inOrder3(node->pLeftChild, minValue, node->value)) {
                return false;
            }
        }
    
        cout << "minValue: " << minValue << " nowValue: " << node->value << " maxValue: " << maxValue << endl;
    
        if (node->value < minValue || node->value > maxValue)
        {
            return false;
        }
    
        if (!inOrder3(node->pRightChild, node->value, maxValue)) {
            return false;
        }
    }
    

    main函数中的测试代码如下:

    void main() {
        PNode node1 = new Node(5);
    
        PNode node2 = new Node(3);
        node1->pLeftChild = node2;
    
        PNode node3 = new Node(8);
        node1->pRightChild = node3;
    
        PNode node4 = new Node(2);
        
        PNode node5 = new Node(4);
    
        node2->pLeftChild = node4;
    
        node2->pRightChild = node5;
    
        PNode node6 = new Node(1);
    
        PNode node7 = new Node(6);
        node3->pLeftChild = node7;
    
        PNode node8 = new Node(7);
        node7->pRightChild = node8;
    
        PNode node9 = new Node(9);
        node3->pRightChild = node9;
    
        node4->pLeftChild = node6;
    
        vector<int> vec;
        cout << "//*****************************方法一************************************//" << endl;
        inOrder1(node1, vec);
    
        bool isBSTree = true;
        for (int i = 0; i < vec.size() - 1; i++) {
            if (vec[i] < vec[i+1]) {
                isBSTree = false;
                break;
            }
        }
    
        if (isBSTree)
        {
            cout << "This is a BSTree" << endl;
        }
        else
        {
            cout << "This is not a BSTree" << endl;
        }
    
        cout << endl;
        cout << "//*****************************方法二************************************//" << endl;
        int lastValue = MIN_INT;
        if (inOrder2(node1, lastValue))
        {
            cout << "This is a BSTree" << endl;
        }
        else
        {
            cout << "This is not a BSTree" << endl;
        }
        cout << endl;
        cout << "//*****************************方法三************************************//" << endl;
    
        int minValue = MIN_INT;
        int maxValue = MAX_INT;
    
        if (inOrder3(node1, minValue, maxValue))
        {
            cout << "This is a BSTree" << endl;
        }
        else
        {
            cout << "This is not a BSTree" << endl;
        }
    
        getchar();
    }
    

    测试结果如下:


    image.png

    相关文章

      网友评论

          本文标题:如何判断一颗二叉树是二叉搜索树(BSTree)

          本文链接:https://www.haomeiwen.com/subject/tiwifftx.html