二叉树的进一步探究

#include<iostream>
#include<queue>
using namespace std;
struct BiNode{
    char data;
    struct BiNode *lchild,*rchild; 
};

void Create(BiNode* &root){
    char c;
    cin>>c;
    if(c=='#') root=NULL;
    else{
        root=new BiNode;
        root->data=c;
        Create(root->lchild);
        Create(root->rchild);
    }
    return ;
}

求二叉树的深度

int getBiTreeDepth(BiNode* root){
    if(root==NULL) 
        return 0;
    else{
        int ldepth=getBiTreeDepth(root->lchild);
        int rdepth=getBiTreeDepth(root->rchild);
        return (ldepth>rdepth?ldepth:rdepth)+1;
    } 
}

求二叉树叶子节点个数

int getBiTreeLeafNum(BiNode* root){
    if(root==NULL) return 0;
    if(root->lchild==NULL&&root->rchild==NULL) return 1;
    else{
        return getBiTreeLeafNum(root->lchild)+ getBiTreeLeafNum(root->rchild);
    }
}

 复制二叉树

BiNode* copyTree(BiNode* root){
    if(root==NULL) return NULL;
    else{
        BiNode* newroot=new BiNode;
        newroot->data=root->data;
        newroot->lchild=copyTree(root->lchild);
        newroot->rchild=copyTree(root->rchild);
        return newroot; 
    }
}

判断是否为完全二叉树

层序遍历之后,如果队列不为空则不是完全二叉树,队列为空则为完全二叉树

完全二叉树有如下特征:

1、叶子结点只可能在层次最大的两层上出现;

2、前k-1层中的结点都是“满”的,且第 k 层的结点都集中在左边。


任意的一个二叉树,都可以将其补成一个满二叉树。这样中间就会有很多空洞。在广度优先遍历的时候,如果是满二叉树,或者完全二叉树,这些空洞是在广度优先的遍历的末尾,所以,但我们遍历到空洞的时候,整个二叉树就已经遍历完成了。而如果遍历到空洞的时候,整个二叉树还没有遍历完成,则是非完全二叉树,

我们遍历到空洞的时候,就会发现,空洞后面还有没有遍历到的值。这样,只要根据是否遍历到空洞,整个树的遍历是否结束来判断是否是完全的二叉树。

bool isCompleteBiTree(BiNode* root){
    if(root==NULL) return false;
    queue<BiNode*> q;
    q.push(root);
    while(!q.empty()){
        BiNode* tmp=q.front();  
        q.pop();
        if(tmp->lchild!=NULL){
            q.push(tmp->lchild);
        }
        if(tmp->rchild!=NULL){
            q.push(tmp->rchild);
        }
    }
    if(q.empty()) return true;
    else return false;
}

求二叉树总节点数量

int SumNode(BiNode* root){
    if(root==NULL) return 0;
    int left=SumNode(root->lchild);
    int right=SumNode(root->rchild);
    return left+right+1;
}

完整实例

#include<iostream>
#include<queue>
using namespace std;
struct BiNode{
    char data;
    BiNode *lchild,*rchild;
};

void establish(BiNode* &bt){
    char ch;
    cin>>ch;
    if(ch=='#') bt=NULL;
    else{
        bt=new BiNode;
        bt->data=ch;
        establish(bt->lchild);
        establish(bt->rchild);
    }
}
void PreOrder(BiNode* bt){
    if(bt==NULL) return ;
    else{
        cout<<bt->data<<" ";
        PreOrder(bt->lchild);
        PreOrder(bt->rchild);
    }
}
void InOrder(BiNode* bt){
    if(bt==NULL) return ;
    else{
        InOrder(bt->lchild);
        cout<<bt->data<<" ";
        InOrder(bt->rchild);
    }
}
void PostOrder(BiNode* bt){
    if(bt==NULL) return ;
    else{
        PostOrder(bt->lchild);
        PostOrder(bt->rchild);
        cout<<bt->data<<" ";
    }
}
void LeverOrder(BiNode* bt){
    if(bt==NULL) return;
    queue<BiNode*> q;
    q.push(bt);
    while(!q.empty()){
        BiNode* tmp=q.front();
        q.pop();
        cout<<tmp->data<<" ";
        if(tmp->lchild!=NULL){
            q.push(tmp->lchild);
        }
        if(tmp->rchild!=NULL){
            q.push(tmp->rchild);
        }
     }
}
void deleteBiTree(BiNode* &bt){
    if(bt!=NULL){
        deleteBiTree(bt->lchild);
        deleteBiTree(bt->rchild);
        cout<<"delete:"<<bt->data<<" ";
        delete bt;
        bt=NULL;
    }
}
int getLeaf(BiNode* bt){
    if(bt==NULL) return 0;
    if(bt->lchild==NULL&&bt->rchild==NULL) return 1;
    return getLeaf(bt->lchild)+getLeaf(bt->rchild);
}
int getNode(BiNode* bt){
    if(bt==NULL ) return 0;
    return getNode(bt->lchild)+getNode(bt->rchild)+1;
}
int getDepth(BiNode* bt){
    if(bt==NULL) return 0;
    int left=getDepth(bt->lchild);
    int right=getDepth(bt->rchild);
    return (left>right?left:right)+1;
}
BiNode* copyBiTree(BiNode* bt){
    if(bt==NULL) return NULL;
    else{
        BiNode* newroot=new BiNode;
        newroot->data=bt->data;
        newroot->lchild=(bt->lchild);
        newroot->rchild=(bt->rchild);
        return newroot;
    }
}
bool isCompleteBiTree(BiNode* bt){
    if(bt==NULL) return false;
    else{
        queue<BiNode*> q;
        q.push(bt);
        while(!q.empty()){
            BiNode* tmp=q.front();
            q.pop();
            if(tmp->lchild!=NULL) {
                isCompleteBiTree(tmp->lchild);
            }
            if(tmp->rchild!=NULL){
                isCompleteBiTree(tmp->rchild);
            } 
        }
        if(q.empty()) return true;
        else return false;
    } 
}
int main(){
    BiNode* root;
    establish(root);
    PreOrder(root);
    cout<<endl;
    InOrder(root);
    cout<<endl;
    PostOrder(root);
    cout<<endl;
    LeverOrder(root);
    cout<<endl;
    cout<<"叶子节点数是:"<<getLeaf(root)<<endl;
    cout<<"总节点数是:"<<getNode(root)<<endl;
    cout<<"深度是:"<<getDepth(root)<<endl; 
    BiNode* newroot=copyBiTree(root);
    PreOrder(newroot);
    cout<<endl; 
    if(isCompleteBiTree(root)) cout<<"是完全二叉树"<<endl;
    else cout<<"不是完全二叉树"<<endl;
    deleteBiTree(root);
    return 0;
}

输入:AB#D##C##

输出:

A B D C
B D A C
D B C A
A B C D
叶子节点数是:2
总节点数是:4
深度是:3
A B D C
是完全二叉树
delete:D delete:B delete:C delete:A

posted @ 2021-03-26 18:35  gonghr  阅读(101)  评论(0)    收藏  举报