1. 程式人生 > >C++ 判斷一顆樹騰訊分是分網站開發否是BST(二叉排序樹)

C++ 判斷一顆樹騰訊分是分網站開發否是BST(二叉排序樹)

sizeof 存儲 tno ret turn bre 打印 二叉 添加

因為騰訊分分網站開發 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);
}

運行結果如下:

C++ 判斷一顆樹騰訊分是分網站開發否是BST(二叉排序樹)