二叉树知识点

高度为h的平衡二叉树

最少包含的节点个数为:

f(1) = 1,f(2)=2,f(3)=4,f(4)=7............f(n+2) = f(n+1)+f(n)+1.

最少包含的叶节点个数为:

f(1)=1,f(2)=1,f(3)=2,f(4)=3,f(5)=5,f(6)=8.......f(n+2)=f(n+1)+f(n).//斐波那契数列。


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


class binaryTreeNode{
public:
    int el;
    binaryTreeNode * left;
    binaryTreeNode * right;
    binaryTreeNode(){
        left = right = 0;
    }
    binaryTreeNode(const int e,binaryTreeNode*l=0,binaryTreeNode*r=0){
        el=e;
        left = l;
        right = r;
    }
};


class binaryTree{
public:
    binaryTree(){
        root = 0;
    }
    binaryTree(binaryTreeNode*r){
        root = r;
    }
    bool isEmpty()const{
        return root==0;
    }
    int GetNum(){//求二叉树的节点个数
        return GetNum(root);
    }
    int deep(){//求二叉树的深度
        return deep(root);
    }
    //递归深度优先遍历
    void prorder(){
        prorder(root);
    }
    void inorder(){
        inorder(root);
    }
    void postorder(){
        postorder(root);
    }
    //用队列实现广度优先遍历
    void levelTravel(){
        levelTravel(root);
    }
    //求二叉树第k层的节点个数
    int getNumKLevel(int k){
        getNumKLevel(root,k);
    }
    //求二叉树中叶节点的个数
    int leafNum(){
        return leafNum(root);
    }
    //判断两棵二叉树是否结构相同
    bool strcmp(binaryTree&t){
        return strcmp(root,t.root);
    }
    //判断二叉树是否为平衡二叉树
    bool isAVL(){
        return isAVL(root);
    }
    //求二叉树的镜像
    binaryTree Mirror(){
        return binaryTree(Mirror(root));
    }
    //求二叉树种两个节点的最低公共祖先
    binaryTreeNode* getLastCommonParent(binaryTreeNode*p1,binaryTreeNode*p2){
        return getLastCommonParent(root,p1,p2);
    }
    //非递归的深度优先遍历
    void iterproder();
    void iterinorder();
    void iterpostorder();
    //判断二叉树是否是完全二叉树
    bool isComplate(){
        return isComplate(root);
    }
    //判断是否是二叉排序树
    bool isBinarySort(){
        return isBinarySort(root);
    }


protected:
    binaryTreeNode * root;
    int GetNum(binaryTreeNode*);//二叉树的节点个数
    int deep(binaryTreeNode*);//二叉树的深度
    virtual void visit(binaryTreeNode*p){
        cout<<p->el<<" ";
    }
    //递归深度优先遍历
    void prorder(binaryTreeNode*);
    void inorder(binaryTreeNode*);
    void postorder(binaryTreeNode*);
    //广度优先遍历
    void levelTravel(binaryTreeNode*);
    //求二叉树第K层的节点个数
    getNumKLevel(binaryTreeNode*,int);
    //求二叉树中叶节点的个数
    int leafNum(binaryTreeNode*);
    //判断两棵二叉树是否相同
    bool strcmp(binaryTreeNode*,binaryTreeNode*);
    //判断二叉树是否为平衡二叉树
    bool isAVL(binaryTreeNode*);
    //求二叉树的镜像
    binaryTreeNode* Mirror(binaryTreeNode*);
    //求二叉树种两个节点的最低公共祖先
    bool foundNode(binaryTreeNode*,binaryTreeNode*);
    binaryTreeNode* getLastCommonParent(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);
    bool getNodePath(binaryTreeNode*,binaryTreeNode*,list<binaryTreeNode*>&);
    binaryTreeNode* getLastCommonParent2(binaryTreeNode*,binaryTreeNode*,binaryTreeNode*);
    //判断是否是完全二叉树
    bool isComplate(binaryTreeNode*);
    //判断是否是二叉排序树
    bool isBinarySort(binaryTreeNode*);


};
//二叉树的节点个数
int binaryTree::GetNum(binaryTreeNode*p){
    if(p==0)
        return 0;
    else
        return 1+GetNum(p->left)+GetNum(p->right);
}


//二叉树的深度
int binaryTree::deep(binaryTreeNode*p){
    if(p==0)
        return 0;
    else
        return 1+(deep(p->left)>deep(p->right))?deep(p->left):deep(p->right);
}
//3种递归深度优先遍历
void binaryTree::prorder(binaryTreeNode*p){
    if(p!=0)
    {
    visit(p);
    prorder(p->left);
    prorder(p->right);
    }
}


void binaryTree::inorder(binaryTreeNode*p){
    if(p!=0){
        inorder(p->left);
        visit(p);
        inorder(p->right);
    }
}
void binaryTree::postorder(binaryTreeNode*p){
    if(p!=0){
        postorder(p->left);
        postorder(p->right);
        visit(p);
    }
}
//用队列实现广度优先遍历
void binaryTree::levelTravel(binaryTreeNode*p){
    queue<binaryTreeNode*> q;
    binaryTreeNode * t;
    if(p!=0)
    {
        q.push(p);
        while(!q.empty()){
            t = q.front();
            visit(t);
            q.pop();
            if(t->left);
            q.push(t->left);
            if(t->right)
            q.push(t->right);
        }
    }
}
//求二叉树第K层的节点个数
int binaryTree::getNumKLevel(binaryTreeNode*p,int k){
    if(p==0||k<1)
        return 0;
    else if(k==1)
        return 1;
    return (getNumKLevel(p->left,k-1)+getNumKLevel(p->right,k-1));
}


//求二叉树中叶节点的个数
int binaryTree::leafNum(binaryTreeNode*p){
    if(p==0)
        return 0;
    else if(p->left==0&&p->right==0)
        return 1;
    else
        return (leafNum(p->right)+leafNum(p->left));
}
//判断两棵二叉树是否相同
bool binaryTree::strcmp(binaryTreeNode*p1,binaryTreeNode*p2){
    if(p1==0&&p2==0)
        return true;
    else if(p1==0||p2==0)
        return false;
    else
        return strcmp(p1->left,p2->left)&&(p1->right,p2->right);
}
//判断是否为平衡二叉树
bool binaryTree::isAVL(binaryTreeNode*p){
    if(p==0)
        return true;
    int left = deep(p->left);
    int right = deep(p->right);
    int diff = right - left;
    if(diff <=-1 || diff >= 1)
        return false;
    return(isAVL(p->left)&&isAVL(p->right));
}
//求二叉树的镜像
binaryTreeNode* binaryTree::Mirror(binaryTreeNode*p){
    binaryTreeNode * p1;
    if(p==0)
        return 0;
    binaryTreeNode * pl = Mirror(p->left);
    binaryTreeNode * pr = Mirror(p->right);
    p1->left = pr;
    p1->right = pl;
    return p1;
}
//求二叉树种两个节点的最低公共祖先
bool binaryTree::foundNode(binaryTreeNode*p1,binaryTreeNode*p2){
    if(p1==0||p2==0)
        return false;
    if(p1==p2)
        return true;
    bool found = foundNode(p1->left,p2);
    if(!found)
    found = foundNode(p1->right,p2);
    return found;
}
//递归解法:
//如果两个节点分别在根节点的左子树和右子树,则返回根节点
//如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
binaryTreeNode* binaryTree::getLastCommonParent(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){
    if(foundNode(r->left,p1)){
        if(foundNode(r->right,p2))
            return r;
        else
            return getLastCommonParent(r->left,p1,p2);
    }
    else{
        if(foundNode(r->left,p2))
            return r;
        else
            return getLastCommonParent(r->right,p1,p2);
    }
}
//非递归解法:
//先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点
bool binaryTree::getNodePath(binaryTreeNode*r,binaryTreeNode*p,list<binaryTreeNode*>&path){
    if(r==p){
        path.push_back(r);
        return true;
    }
    if(r==0)
        return false;
    path.push_back(r);
    bool found = false;
    found = getNodePath(r->left,p,path);
    if(!found)
    found = getNodePath(r->right,p,path);
    if(!found)
        path.pop_back();
    return found;
}
binaryTreeNode*binaryTree::getLastCommonParent2(binaryTreeNode*r,binaryTreeNode*p1,binaryTreeNode*p2){
    if(r==0||p1==0||p2==0)
        return nullptr;
    list<binaryTreeNode*>path1;
    bool bresult1 = getNodePath(r,p1,path1);
    list<binaryTreeNode*>path2;
    bool bresult2 = getNodePath(r,p2,path2);
    if(!bresult1||!bresult2)
        return nullptr;
    binaryTreeNode * pLast = NULL;
    list<binaryTreeNode*>::const_iterator iter1 = path1.begin();
    list<binaryTreeNode*>::const_iterator iter2 = path2.begin();
    while(iter1!=path1.end()&&iter2!=path2.end()){
        if(*iter1 == *iter2)
            pLast = *iter1;
        iter1++;
        iter2++;
    }
    return pLast;
}
//非递归先序遍历
void binaryTree::iterproder(){
    stack<binaryTreeNode*> s;
    binaryTreeNode*p = root;
    if(p!=0){
        s.push(p);
    while(!s.empty()){
        p = s.top();
        s.pop();
        visit(p);
        if(p->right!=0)
            s.push(p->right);
        if(p->left!=0)
            s.push(p->left);
    }
    }
}
//非递归中序遍历
//若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理
//若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子
void binaryTree::iterinorder(){
    binaryTreeNode * p =root;
    stack<binaryTreeNode*>s;
    while(p!=0||!s.empty()){
        while(p!=0){
            s.push(p);
            p=p->left;
        }
        if(!s.empty()){
            p=s.top();
            visit(p);
            s.pop();
            p=p->right;
        }
    }
}


//非递归后序遍历
/*对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,
但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,
当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。
这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。
因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
*/
void binaryTree::iterpostorder(){
    stack<binaryTreeNode*>s;
    binaryTreeNode*p = root,*q=root;
    while(p!=0){
        for(;p->left!=0;p=p->left)
            s.push(p);
        while(p->right==0||p->right==q){
            visit(p);
            q=p;
            if(s.empty())
                return;
            p=s.top();
            s.pop();
        }
        s.push(p);
        p=p->right;
    }
}
//判断是否是完全二叉树
bool binaryTree::isComplate(binaryTreeNode*p){
    queue<binaryTreeNode*>q;
    if(p==0)
        return true;
    int tag = 0;
    q.push(p);
    while(!q.empty()){
        p = q.front();
        q.pop();
        if(p->left&&!tag)
            q.push(p->left);
        else if(p->left)
            return false;
        else
            tag =1;
        if(p->right&&!tag)
            q.push(p->right);
        else if(p->right)
            return false;
        else
            tag =1;
    }
    return true;
}


//判断是否是二叉查找树
bool binaryTree::isBinarySort(binaryTreeNode*p){
    binaryTreeNode* pre = 0;
    stack<binaryTreeNode*> s;
    while(p!=0||!s.empty()){
        if(p){
            s.push(p);
            p=p->left;
        }
        else{
            p = s.top();
            s.pop();
            if(pre&&(pre->el>=p->el))
                return false;
            pre = p;
            p=p->right;
        }
    }
    return true;
}
int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值