《面试准备》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;
}

最近公共祖先节点

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL)
            return NULL;
        if(root->val == p->val || root->val == q->val)
            return root;                
        TreeNode* leftN = lowestCommonAncestor(root->left,p,q);
        TreeNode* rightN = lowestCommonAncestor(root->right,p,q);
        if(leftN != NULL && rightN != NULL)
            return root;
        return leftN == NULL ? rightN: leftN ;
    }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值