《面試準備》C++二叉樹操作

參考:https://blog.csdn.net/luckyxiaoqiang/article/details/7518888#topic9

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

//二叉樹節點
struct BTNode{
    int value;
    struct BTNode *pLeft;
    struct BTNode *pRight;
};

class MyBT
{
public:
    MyBT(){}
    ~MyBT(){}
    bool isempty(BTNode *Root);
    void creatBT(BTNode *Root);
    int  cntNode(BTNode *Root);
    int  GetDepth(BTNode *Root);
    int  GetLeafNodeNum(BTNode *Root);
    int  GetNodeNumKthLevel(BTNode *Root,int k);
    void PreOrder(BTNode *Root);
    void InOrder(BTNode *Root);
    void PostOrder(BTNode *Root);
    void LevelTraverse(BTNode *Root);
    bool IsCompleteBinaryTree(BTNode *Root);
};

bool MyBT::isempty(BTNode *Root){
    if(Root->pLeft==NULL&&Root->pRight==NULL)
        return true;
    return false;
}

void MyBT::creatBT(BTNode *Root){
    //左節點
    BTNode *PL = Root;
    BTNode *tmp = new BTNode;
    tmp->value = 1;
    tmp->pLeft = NULL;
    tmp->pRight = NULL;
    PL->pLeft = tmp;
    PL = tmp;
    BTNode *tmp5 = new BTNode;
    tmp5->value = 5;
    tmp5->pLeft = NULL;
    tmp5->pRight = NULL;
    PL->pLeft = tmp5;
    BTNode *tmp6 = new BTNode;
    tmp6->value = 6;
    tmp6->pLeft = NULL;
    tmp6->pRight = NULL;
    PL->pRight = tmp6;
    //右節點
    BTNode *PR = Root;
    BTNode *tmp1 = new BTNode;
    tmp1->value = 2;
    tmp1->pLeft = NULL;
    tmp1->pRight = NULL;
    PR->pRight = tmp1;
    PR = tmp1;
    BTNode *tmp2 = new BTNode;
    tmp2->value = 3;
    tmp2->pLeft = NULL;
    tmp2->pRight = NULL;
    PR->pLeft = tmp2;
//    BTNode *tmp3 = new BTNode;
//    tmp3->value = 4;
//    tmp3->pLeft = NULL;
//    tmp3->pRight = NULL;
//    PR->pRight = tmp3;
}

/*****************求二叉樹中的節點個數(遞歸)********************
 (1)如果二叉樹爲空,節點個數爲0
(2)如果二叉樹不爲空,二叉樹節點個數 = 左子樹節點個數 + 右子樹節點個數 + 1
*/
int MyBT::cntNode(BTNode *Root){
    if(Root==NULL)   //遞歸出口
        return 0;
    //return cntNode(Root->pLeft)+cntNode(Root->pRight)+1;
    int depthLeft = cntNode(Root->pLeft);
    int depthRight = cntNode(Root->pRight);
    return (depthLeft + depthRight + 1);
}

/*****************求二叉樹的深度(遞歸)********************
(1)如果二叉樹爲空,二叉樹的深度爲0
(2)如果二叉樹不爲空,二叉樹的深度 = max(左子樹深度, 右子樹深度) + 1
*/
int MyBT::GetDepth(BTNode *Root){
    if(Root==NULL)   //遞歸出口
        return 0;
    int depthLeft = GetDepth(Root->pLeft);
    int depthRight = GetDepth(Root->pRight);
    return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1);
}

/*****************求二叉樹的葉子節點數目(遞歸)********************
 說明:節點數目 = 內部節點數目+葉子節點數目;
    沒有左右子節點稱爲葉子節點;
 算法:
(1)如果二叉樹爲空,返回0
(2)如果二叉樹不爲空且左右子樹爲空,返回1
(3)如果二叉樹不爲空,且左右子樹不同時爲空,返回左子樹中葉子節點個數加上右子樹中葉子節點個數
*/
int MyBT::GetLeafNodeNum(BTNode *Root){
    if(Root==NULL)
        return 0;
    if(Root->pLeft==NULL && Root->pRight==NULL)
        return 1;
    int depthLeft = GetLeafNodeNum(Root->pLeft);
    int depthRight = GetLeafNodeNum(Root->pRight);
    return (depthLeft + depthRight);
}

/*****************求二叉樹k層數目(遞歸)********************
(1)如果二叉樹爲空或者k<0返回0
(2)如果二叉樹不爲空並且k==0(根節點爲第0層),返回1
(3)如果二叉樹不爲空且k>0,返回左子樹中k-1層的節點個數與右子樹k-1層節點個數之和
*/
int  MyBT::GetNodeNumKthLevel(BTNode *Root,int k){
    if(Root==NULL||k<0)
        return 0;
    if(k==0)
        return 1;
    int depthLeft = GetNodeNumKthLevel(Root->pLeft,k-1);
    int depthRight = GetNodeNumKthLevel(Root->pRight,k-1);
    return (depthLeft + depthRight);
}

/*****************求二叉樹前序遍歷(遞歸)********************
(1)如果二叉樹爲空,空操作
(2)如果二叉樹不爲空,訪問根節點,前序遍歷左子樹,前序遍歷右子樹
*/
void MyBT::PreOrder(BTNode *Root){
    if(Root==NULL)
        return;
    cout<<Root->value<<" ";
    PreOrder(Root->pLeft);
    PreOrder(Root->pRight);
}

/*****************求二叉樹中序遍歷(遞歸)********************
(1)如果二叉樹爲空,空操作。
(2)如果二叉樹不爲空,中序遍歷左子樹,訪問根節點,中序遍歷右子樹
*/
void MyBT::InOrder(BTNode *Root){
    if(Root==NULL)
        return;
    InOrder(Root->pLeft);
    cout<<Root->value<<" ";
    InOrder(Root->pRight);
}

/*****************求二叉樹後序遍歷(遞歸)********************
(1)如果二叉樹爲空,空操作
(2)如果二叉樹不爲空,後序遍歷左子樹,後序遍歷右子樹,訪問根節點
*/
void MyBT::PostOrder(BTNode *Root){
    if(Root==NULL)
        return;
    PostOrder(Root->pLeft);
    PostOrder(Root->pRight);
    cout<<Root->value<<" ";
}

/*****************求二叉樹分層遍歷********************
相當於廣度優先搜索,使用隊列實現。隊列初始化,將根節點壓入隊列。當隊列不爲空,進行如下操作:
彈出一個節點,訪問,若左子節點或右子節點不爲空,將其壓入隊列。
*/
void MyBT::LevelTraverse(BTNode *Root){
    if(Root==NULL)
        return;
    queue<BTNode*>q;
    q.push(Root);
    while (!q.empty()) {
        BTNode *pNode = q.front();
        q.pop();
        cout<<pNode->value<<" ";
        if(pNode->pLeft!=NULL)
            q.push(pNode->pLeft);
        if(pNode->pRight!=NULL)
            q.push(pNode->pRight);
    }
    return;
}

/*****************判斷是否時完全二叉樹********************
按層次(從上到下,從左到右)遍歷二叉樹,當遇到一個節點的左子樹爲空時,則該節點右子樹必須爲空,
且後面遍歷的節點左右子樹都必須爲空,否則不是完全二叉樹。
*/

bool MyBT::IsCompleteBinaryTree(BTNode *Root){
    if(Root==NULL)
        return false;
    bool havenochild = false;
    bool result = true;
    queue<BTNode*>q;
    q.push(Root);
    while (!q.empty()) {
        BTNode *pNode = q.front();
        q.pop();
        if(havenochild){
            if(pNode->pLeft!=NULL||pNode->pRight!=NULL){
                return false;
                break;
            }
        }
        else{
            if(pNode->pLeft!=NULL&&pNode->pRight!=NULL){
                q.push(pNode->pLeft);
                q.push(pNode->pRight);
            }
            else if(pNode->pLeft!=NULL&&pNode->pRight==NULL){
                havenochild = true;
                q.push(pNode->pLeft);
            }
            else if(pNode->pLeft==NULL&&pNode->pRight!=NULL){
                return false;
                break;
            }
            else
                havenochild = true;
        }

    }
    return result;
}

int main ()
{
    MyBT *mybt = new MyBT();
    BTNode *Root = new BTNode;
    mybt->creatBT(Root);
    cout<<"是否爲空 : "<<mybt->isempty(Root)<<endl;
    cout<<"節點個數 : "<<mybt->cntNode(Root)<<endl;
    cout<<"節點深度 : "<<mybt->GetDepth(Root)<<endl;
    cout<<"葉子節點數目 : "<<mybt->GetLeafNodeNum(Root)<<endl;
    cout<<"第k層的節點數 : "<<mybt->GetNodeNumKthLevel(Root,2)<<endl;
    cout<<"是否時完全二叉樹 : "<<mybt->IsCompleteBinaryTree(Root)<<endl;
    cout<<"前序遍歷 : ";
    mybt->PreOrder(Root);
    cout<<endl;
    cout<<"中序遍歷 : ";
    mybt->InOrder(Root);
    cout<<endl;
    cout<<"後序遍歷 : ";
    mybt->PostOrder(Root);
    cout<<endl;
    cout<<"分層遍歷 : ";
    mybt->LevelTraverse(Root);
    cout<<endl;

    delete mybt;
    mybt = NULL;
    delete Root;
    Root =NULL;
    return 0;
}

 

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