判斷是否爲二叉搜索樹(C++實現)

給定一個根結點如何判斷一棵樹是否爲二叉搜索樹呢?下面我們用三種方式來處理這個問題

方法一:

根據二叉搜索樹的特徵,二叉搜索樹的中序遍歷應該爲一個有序集合

  1. 對樹進行中序遍歷,將結果保存在temp數組中

  2. 檢測temp數組是否爲升序排列,如果是,則爲BST,反之則不是

//這裏爲了好理解就直接使用遞歸寫
void inOrder(TreeNode* tmp, vector<int>& arr)
{
    if(tmp->left)
        inOrder(tmp->left, arr);
    arr.push_back(tmp->value);
    if(tmp->right)
        inOrder(tmp->right, arr);
}


bool isBST(TreeNode* root)
{
    vector<int> arr;
    inOrder(root, arr);
    int index = 1;
    while(arr.size() > index){
        if(arr[index] < arr[index - 1])
            return false;
    }
    return true;
}

此方法還可以進一步的優化,不用temp數組,避免使用額外的內存開銷。在中序遍歷時使用靜態變量保存前驅節點,如果當前節點小於前驅節點,則該樹不是BST

bool isBST(TreeNode *root)
{
    //靜態結點僅在第一次調用時創建
    static TreeNode *prev;
    if(root != NULL)
    {
        if(!isBST(root->left))
            return false;
        if(prev != NULL && root->data < prev->data)
            return false;
        prev = root;
        if(!isBST(root->right))
            return false;
    }
    return true;
}

方法二:

暴力法:該方法的思路最切合二叉搜索樹的概念(比較當前節點是否比左子樹最大節點大,比右子樹最小結點小)

int maxValue(TreeNode *root)
{
    int max = root->data;
    if(root->left != NULL)
    {
        int maxLeft = maxValue(root->left);
        max = max > maxLeft ? max : maxLeft;
    }
    if(root->right != NULL)
    {
        int maxRight = maxValue(root->right);
        max = max > maxRight ? max : maxRight;
    }
    return max;
}


int minValue(TreeNode *root)
{
    int min = root->data;
    if(root->left != NULL)
    {
        int minLeft = maxValue(root->left);
        min = min > minLeft ? min : minLeft;
    }
    if(root->right != NULL)
    {
        int minRight = maxValue(root->right);
        min = min > minRight ? min : minRight;
    }
    return min;
}


bool isBST(TreeNode *root)
{
    if(root == NULL)
        return true;
    if(root->left != NULL && maxValue(root->left) > root->data)
        return false;
    if(root->right != NULL && minValue(root->right) < root->data)
        return false;
    return isBST(root->left) && isBST(root->right);
}

方法三:

討巧的方法,將樹結點值的範圍確定,所有節點的值滿足該範圍即爲二叉搜索樹

bool isBSTUtil(TreeNode *root, int min, int max)
{
    if(root == NULL)
        return true;
    if(root->data < min || root->data > max)
        return false;
    return isBSTUtil(root->left, min, root->data - 1) && isBSTUtil(root->right, root->data + 1, max);
}


bool isBST(TreeNode *root)
{
    //節點值的初始範圍可限定爲TNT_MIN以及TNT_MAX
    return isBST02(root, INT_MIN, INT_MAX);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章