C++ 判断一颗树腾讯分是分网站开发否是BST(二叉排序树)

因为腾讯分分网站开发 haozbbs.com Q1446595067二叉排序树的中序遍历结果是递增的,所以可以通过中序遍历存储结果,再判断是否为递增的数组。
1) 对树进行中序遍历,将结果保存在b[]数组中。
2) 检测b[]数组中元素是否为升序排列。如果是,则这棵树为BST.
时间复杂度: O(n)

代码如下:

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

typedef struct BinaryTreeNode{
    int value;
    BinaryTreeNode *m_pLeft;
    BinaryTreeNode *m_pRight;
}BTNode;

int max_height = -1;

void addBTNode(BTNode *&myBT,int val);//添加节点 
void createBT(BTNode *&BT,int arr[],int n);//创建二叉排序树,通过*&来改变指针的值

void midorder_showBT(BTNode *myBT);//中序遍历打印,如果是二叉排序树,打印结果与单调递增数组一样

int b[100];
int idx = 0;
void is_BST(BTNode *myBT);//判断是否是二叉排序树 

int main(){

    BTNode *myBT = nullptr;

    int arr[10] = {314,426,12,78,143,8,21,14,9,314};
    createBT(myBT,arr,10);

    midorder_showBT(myBT);
    cout<<endl;

    is_BST(myBT);
    bool isBT = true;
    if(idx == 1 || idx == 0)
        cout<<"是BST"<<endl;
    else{
        for(int i=0;i < idx - 1;i++){
            if(b[i] >= b[i+1]){
                isBT = false;
                break;
            }
        } 
        if(isBT)
            cout<<"是BST"<<endl;
        else
            cout<<"不是BST"<<endl;    
    } 

    return 0;
}

void is_BST(BTNode *myBT){
    if(myBT == nullptr )
        return ;
    is_BST(myBT->m_pLeft);
    b[idx++] = myBT->value;
    is_BST(myBT->m_pRight);
}

void createBT(BTNode *&BT,int arr[],int n){
    BT = nullptr;
    for(int i=0;i<n;i++)
        addBTNode(BT,arr[i]);   
}

void addBTNode(BTNode *&myBT,int val){
    if(myBT == nullptr){
        myBT = new BinaryTreeNode();
        myBT->value = val;
        myBT->m_pLeft = nullptr;
        myBT->m_pRight = nullptr;
        return; 
    }

    if(val == myBT->value){
        return;
    }
    else if(val < myBT->value){
        addBTNode(myBT->m_pLeft,val);
    }
    else{
        addBTNode(myBT->m_pRight,val);
    }           
}

void midorder_showBT(BTNode *myBT){//中序遍历打印 {
    if(myBT == nullptr )
        return;

    midorder_showBT(myBT->m_pLeft);
    cout<<myBT->value<<" ";
    midorder_showBT(myBT->m_pRight);
} 

方法二:限定二叉树中节点值的范围,优化算法每个节点只需访问一次

限定了子树中节点值的范围,从而每个节点只需访问一次。节点值的初始范围可限定为INT_MIN以及INT_MAX。
//判断是否为BST
bool is_BT(BTNode *myBT,int min,int max){
if(myBT == nullptr || min > max)
return false;
return is_BT_Core(myBT,min,max);
}
//如果是一颗二叉查找树,且值范围在[min,max],则返回true

bool is_BT_Core(BTNode *myBT,int min,int max);

代码实现如下:

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

typedef struct BinaryTreeNode{
    int value;
    BinaryTreeNode *m_pLeft;
    BinaryTreeNode *m_pRight;
}BTNode;

int max_height = -1;

void addBTNode(BTNode *&myBT,int val);//添加节点 
void createBT(BTNode *&BT,int arr[],int n);//创建二叉排序树,通过*&来改变指针的值
void midorder_showBT(BTNode *myBT);//中序遍历打印,如果是二叉排序树,打印结果与单调递增数组一样

bool is_BT(BTNode *myBT,int min,int max);//判断是否是BST(二叉排序树) 
bool is_BT_Core(BTNode *myBT,int min,int max);//判断是否是BST(二叉排序树) 核心函数

int min_val = 1,max_val = 1000; 

int main(){

    BTNode *myBT = nullptr;

    int arr[] = {314,426,12,78,143,8,21,14,9,314};
    createBT(myBT,arr,sizeof(arr)/sizeof(arr[0]));

    cout<<"中序遍历结果:"<<endl; 
    midorder_showBT(myBT);
    cout<<endl;

    if(is_BT(myBT,min_val,max_val)){
        cout<<"此二叉树是BST"<<endl; 
    }else
        cout<<"此二叉树不是BST"<<endl; 

    return 0;
}

bool is_BT(BTNode *myBT,int min,int max){
    if(myBT == nullptr || min > max)
        return false;//空子树返回false 
    return is_BT_Core(myBT,min,max);
}

bool is_BT_Core(BTNode *myBT,int min,int max){
    if(myBT == nullptr)//空结点时返回true结束 
        return true;

    //如果节点值违反了最大/最小约束条件,则不是BST
    if( (myBT->value < min) || (myBT->value > max) )
        return false;

    return is_BT_Core(myBT->m_pLeft,min,myBT->value - 1) 
           && is_BT_Core(myBT->m_pRight,myBT->value + 1,max);
}

void createBT(BTNode *&BT,int arr[],int n){
    BT = nullptr;
    for(int i=0;i<n;i++)
        addBTNode(BT,arr[i]);   
}

void addBTNode(BTNode *&myBT,int val){
    if(myBT == nullptr){
        myBT = new BinaryTreeNode();
        myBT->value = val;
        myBT->m_pLeft = nullptr;
        myBT->m_pRight = nullptr;
        return; 
    }

    if(val == myBT->value){
        return;
    }
    else if(val < myBT->value){
        addBTNode(myBT->m_pLeft,val);
    }
    else{
        addBTNode(myBT->m_pRight,val);
    }           
}

void midorder_showBT(BTNode *myBT){//中序遍历打印 {
    if(myBT == nullptr )
        return;

    midorder_showBT(myBT->m_pLeft);
    cout<<myBT->value<<" ";
    midorder_showBT(myBT->m_pRight);
}

运行结果如下:

猜你喜欢

转载自blog.51cto.com/13860140/2139394