二叉树的基本操作(C++实现)

编译器是DevC++。可能有地方写得不够规范,大佬轻喷。

//链式存储的二叉树 
//先序建立方式
//遍历方式:先序,中序,后序,层次 
//计算:树的深度,叶子节点,节点数,度为1的节点数,度为2的节点数
//二叉树的复制,交换左右子树
//二叉树的查找,修改,删除,插入 


#include<iostream>
#include<string.h>
#include<queue>

using namespace std;

int n;

typedef struct Node{
    
    int data;
    Node *lchild,*rchild;
    
}LkNode,*BiTree;


void CreateBiTree(BiTree &T){
    
    int inputdata;
    cin>>inputdata;
    if(inputdata == -1){
        
        T = NULL;
        //return;
        
    }
    
    else{
        
        T = new LkNode();
        if(!T)
            cout<<"开辟空间失败!"<<endl;
        else{
            
            T ->data = inputdata; //创建根节点
            CreateBiTree(T ->lchild);
            CreateBiTree(T ->rchild);
            
        }
        
    }
    
}


void PreOrederTraverse(BiTree T){ //递归实现先序遍历 
    
    if(T != NULL){
        
        cout<<T ->data<<" ";
        PreOrederTraverse(T ->lchild);
        PreOrederTraverse(T ->rchild);
        
    }
    else{
        
        //cout<<"二叉树为空!"<<endl;
        return;
        
    }
    
}


void MidOrederTraverse(BiTree T){ //递归实现中序遍历
    
    if(T != NULL){
        
        MidOrederTraverse(T ->lchild);
        cout<<T ->data<<" ";
        MidOrederTraverse(T ->rchild);
         
    }
    else{
        
        //cout<<"二叉树为空!"<<endl;
        return;
        
    }
    
}


void LastOrederTraverse(BiTree T){ //递归实现后序遍历 
    
    if(T != NULL){
        
        LastOrederTraverse(T ->lchild);
        LastOrederTraverse(T ->rchild);
        cout<<T ->data<<" ";
         
    }
    else{
        
        //cout<<"二叉树为空!"<<endl;
        return;
        
    }
    
}


void LevelTraverse(BiTree T){ //队列实现层次遍历
    
    queue<BiTree> que;
    if(T != NULL){
        
        while(T){

            cout << T->data << " ";

            if(T->lchild)
                que.push(T->lchild);
            if(T->rchild)
                que.push(T->rchild);
            if(que.empty())
                break;

            T = que.front(); //将队列首元素赋予T, 
            que.pop();

        }
        
    }
    else{
        
        //cout<<"二叉树为空!"<<endl;
        return;
        
    }
    
}


int DepthBiTree(BiTree T){ //计算二叉树的深度 
    
    int dep = 0,depl,depr;
    if(!T)
        return 0;
    else{
        
        depl = DepthBiTree(T ->lchild);
        depr = DepthBiTree(T ->rchild);
        dep = 1 + (depl > depr ? depl : depr);
        return dep;
            
    }
    
}


int NodeCount(BiTree T){ //计算节点数 
    
    int nodecount = 0;
    if(!T)
        return 0;
    else{
        
        //return NodeCount(T ->lchild) +NodeCount(T ->rchild) + 1;
        nodecount++;
        
        nodecount += NodeCount(T ->lchild);
        nodecount += NodeCount(T ->rchild);
        
    }
    return nodecount;
        
}


int LeafCount(BiTree T){ //计算叶子节点数 
    
    int leafcount = 0;
    if(!T)
        return 0;
    else{
        
        if( (!T ->lchild) && (!T ->rchild) ) //左右子树均为空,则为叶子节点 
            //leafcount++; //两种写法都可以 
            leafcount = 1;
        
        leafcount += LeafCount(T ->lchild);
        leafcount += LeafCount(T ->rchild);
            
    }
    return leafcount;
    
}
    

int SinglePointCount(BiTree T){ //计算度为1的节点数
    
    int sgcount = 0;
    if(!T)
        return 0;
    else{
        
        if( T ->lchild && T ->rchild ){ //左右节点都不为空,则分别计算左右子树度为1的节点个数 
            
            sgcount += SinglePointCount(T ->lchild);
            sgcount += SinglePointCount(T ->rchild);
            
        }
        if( T ->lchild && (!T ->rchild) ){ //左节点不为空,计算左子树度为1的节点个数 
            
            sgcount++;
            sgcount += SinglePointCount(T ->lchild);
            
        }
        if( (!T ->lchild) && T ->rchild ){ //右节点不为空,计算右子树度为1的节点个数 
            
            sgcount++;
            sgcount += SinglePointCount(T ->rchild);
            
        }
        
    }
    return sgcount;
        
}


int DoublePointCount(BiTree T){ //计算度为2的节点数 
    
    int dbcount = 0;
    if(!T)
        return 0;
    else{
        
        if( T ->lchild && T ->rchild ) //左右子树均不为空,则度为2
            dbcount++;
        
        dbcount += DoublePointCount(T ->lchild);
        dbcount += DoublePointCount(T ->rchild);
        
    }
    return dbcount;
    
}
        

void SwapBiTree(BiTree &T){ //交换左右子树所有节点 
    
    BiTree tem = new LkNode();
    if(T){
        
        tem = T ->rchild;
        T ->rchild = T ->lchild;
        T ->lchild = tem;
        
        SwapBiTree(T ->lchild);
        SwapBiTree(T ->rchild);
        
    }
    else return;
    
}


void CopyBiTree(BiTree T,BiTree &T2){ //复制二叉树 
    
    T2 = new LkNode();
    if(T){
        
        T2 ->data = T ->data;
        CopyBiTree(T ->lchild,T2 ->lchild);
        CopyBiTree(T ->rchild,T2 ->rchild);
        
    }
    else{
        
        T2 = NULL;
        return;
        
    }
    
}


bool SearchNode(BiTree T,int search){ //查找节点 
    
    if(T){
        
        if(T ->data == search){
            
            cout<<"节点"<<search<<"存在,";
            if(T ->lchild && T ->rchild){
                
                cout<<"且节点"<<search<<"的左孩子为"<<T ->lchild ->data;
                cout<<",右孩子为"<<T ->rchild ->data<<"。"<<endl;
                
            }
            else if(T ->lchild && (!T ->rchild)){
                
                cout<<"且节点"<<search<<"的左孩子为"<<T ->lchild ->data;
                cout<<",右孩子为空。"<<endl;
                
            }
            else if((!T ->lchild) && T ->rchild){
                
                cout<<"且节点"<<search<<"的左孩子为空";
                cout<<",右孩子为"<<T ->rchild ->data<<"。"<<endl;
                
            }
            else
                cout<<"该节点无左右孩子。"<<endl; 
            return true; 
            
        }
        else{
            
            bool flag = SearchNode(T ->lchild,search);
            if(flag)
            {}
            else
                SearchNode(T ->rchild,search);
            
        }
        
    }
    else
        return false;
    
}


void GetParent(BiTree T,int search){ //查找父节点 
    
    if(T ->lchild){
        
        if(T ->lchild ->data == search){
            
            cout<<"节点"<<search<<"为父节点"<<T ->data<<"的左孩子。"<<endl;
            return;
            
        }
        else
            GetParent(T ->lchild,search);
            
    }
    if(T ->rchild){
        
        if(T ->rchild ->data == search){
            
            cout<<"节点"<<search<<"为父节点"<<T ->data<<"的右孩子。"<<endl;
            return;
            
        }
        else
            GetParent(T ->rchild,search);
            
    }
    if( (!T ->lchild) && (!T ->rchild) )
        return;
        
}


bool UpdateNode(BiTree &T,int update){ //修改节点 
    
    if(T){
        
        if(T ->data == update){
            
            int update2;
            cout<<"节点"<<update<<"存在,请输入更改后的数据:";
            cin>>update2;
            
            T ->data = update2;
            return true; 
            
        }
        else{
            
            bool flag = UpdateNode(T ->lchild,update);
            if(flag)
            {}
            else
                UpdateNode(T ->rchild,update);
            
        }
        
    }
    else
        return false;
    
}


bool DeleteNode(BiTree &T,int dlt){ //删除节点
    
    if(T){
        
        if(T ->data == dlt){
            
            if(T ->lchild && T ->rchild){ //用左孩子替代原节点,右孩子变成左孩子的左孩子 
                
                BiTree tem = T ->rchild;
                T = T ->lchild; //可以写个if,左右节点谁大谁替代原节点 
                T ->lchild = tem;
                T ->rchild = NULL;
                
            }
            else if(T ->lchild && (!T ->rchild)){ //用左孩子替代原节点 
                
                T = T ->lchild;
                
            }
            else if((!T ->lchild) && T ->rchild){ //用右孩子替代原节点 
                
                T = T ->rchild;
                
            }
            else
                T = NULL;
            
            //T = NULL; //连同左右孩子一起删除 
            return true; 
            
        }
        else{
            
            bool flag = DeleteNode(T ->lchild,dlt);
            if(flag)
            {}
            else
                DeleteNode(T ->rchild,dlt);
            
        }
        
    }
    else
        return false;
    
}


bool InsertNode(BiTree &T,int istparent){ //删除节点
    
    if(T){
        
        if(T ->data == istparent){
            
            int istdata;
            if(T ->lchild && T ->rchild){ //选择插入为原节点的左孩子或右孩子 
                
                cout<<"父节点左右孩子均存在,输入0代表插入为左孩子,输入1代表插入为右孩子。";
                cout<<endl<<"(其它视为空插入)请输入:";
                int lr;
                cin>>lr;
                
                if(lr == 0){
                    
                    cout<<"请输入要插入的数据:";
                    cin>>istdata;
                    BiTree tem = new LkNode(); //开辟新空间
                     
                    tem ->data = istdata;
                    tem ->lchild = T ->lchild; //插入后原节点的左孩子,变成现节点的左孩子
                    tem ->rchild = NULL;
                    T ->lchild = tem;
                    
                }
                else if(lr == 1){
                
                    cout<<"请输入要插入的数据:";
                    cin>>istdata;
                    BiTree tem = new LkNode();
                     
                    tem ->data = istdata;
                    tem ->rchild = T ->rchild; //插入后原节点的右孩子,变成现节点的右孩子
                    tem ->lchild = NULL;
                    T ->rchild = tem;
                    
                }
                else
                    cout<<"插入为空。"<<endl; 
                
            }
            else if(T ->lchild && (!T ->rchild)){ //插入为原节点的右孩子 
                
                cout<<"父节点左孩子存在,右孩子为空,默认插入为右孩子,请输入要插入的数据:";
                cin>>istdata;
                BiTree tem = new LkNode();
            
                tem ->data = istdata;
                T ->rchild = tem; 
                
            }
            else if((!T ->lchild) && T ->rchild){ //插入为原节点的左孩子 
                
                cout<<"父节点左孩子为空,右孩子存在,默认插入为左孩子,请输入要插入的数据:";
                cin>>istdata;
                BiTree tem = new LkNode();
            
                tem ->data = istdata;
                T ->lchild = tem;
                
            }
            else{
                
                cout<<"父节点左右孩子均不存在,默认插入为左孩子,请输入要插入的数据:";
                cin>>istdata;
                
                BiTree istl = new LkNode();
                istl ->data = istdata;
                //istl ->lchild = NULL;
                //istl ->rchild = NULL;
                T ->lchild = istl;
                
            }
            
            return true; 
            
        }
        else{
            
            bool flag = InsertNode(T ->lchild,istparent);
            if(flag)
            {}
            else
                InsertNode(T ->rchild,istparent);
            
        }
        
    }
    else
        return false;
    
}


int main(){
    
    while(1){
        
        BiTree tree = NULL; //创建从根节点开始的二叉树
         
        cout<<"请输入二叉树tree的节点:";
        CreateBiTree(tree);
        cout<<"二叉树tree创建成功!"<<endl;
        
        cout<<"先序遍历的顺序为:";
        PreOrederTraverse(tree);
        cout<<endl;
        
        cout<<"中序遍历的顺序为:";
        MidOrederTraverse(tree);
        cout<<endl;
        
        cout<<"后序遍历的顺序为:";
        LastOrederTraverse(tree);
        cout<<endl;
        
        cout<<"层次遍历的顺序为:";
        LevelTraverse(tree);
        cout<<endl;
        
        cout<<"二叉树tree的深度为:"<<DepthBiTree(tree)<<endl;
        cout<<"二叉树tree的节点数为:"<<NodeCount(tree)<<endl;
        cout<<"其中:"<<endl; 
        cout<<"叶子节点数为:"<<LeafCount(tree)<<endl;
        cout<<"度为1的节点数为:"<<SinglePointCount(tree)<<endl;
        cout<<"度为2的节点数为:"<<DoublePointCount(tree)<<endl;
        
        BiTree tree2 = NULL;
        CopyBiTree(tree,tree2);
        cout<<"将二叉树tree复制到tree2后,tree2层次遍历的顺序为:";
        LevelTraverse(tree2); 
        cout<<endl;
        
        SwapBiTree(tree2);
        cout<<"交换tree2左右子树所有结点后,tree2层次遍历的顺序为:";
        LevelTraverse(tree2); 
        cout<<endl;
        
        int srh;
        cout<<"请输入tree中你要查找的节点:"; 
        cin>>srh;
        if(SearchNode(tree,srh)){
        
            if(tree ->data == srh)
                cout<<"节点"<<srh<<"为根节点,无父节点。"<<endl; 
            else
                GetParent(tree,srh);
            
        }
        else
            cout<<"查找节点不存在!"<<endl; 
        
        int upt; 
        cout<<"请输入tree中你要更改的节点:";
        cin>>upt;
        if(UpdateNode(tree,upt)){
        
            cout<<"修改成功!修改后tree层次遍历的顺序为:";
            LevelTraverse(tree); 
            cout<<endl; 
            
        }
        else
            cout<<"修改节点不存在!"<<endl; 
        
        int dlt; 
        cout<<"请输入tree中你要删除的节点:";
        cin>>dlt;
        if(DeleteNode(tree,dlt)){
        
            cout<<"删除成功!删除后tree层次遍历的顺序为:";
            LevelTraverse(tree); 
            cout<<endl; 
            
        }
        else
            cout<<"删除节点不存在!"<<endl; 
        
        int istparent; 
        cout<<"请输入tree中你要插入节点的父节点:";
        cin>>istparent;
        if(InsertNode(tree,istparent)){
        
            cout<<"插入成功!插入后tree层次遍历的顺序为:";
            LevelTraverse(tree); 
            cout<<endl; 
            
        }
        else
            cout<<"要插入节点的父节点不存在!"<<endl; 
        
    }
    
}
        

/*测试样例:
1 2 4 8 -1 -1 -1 5 9 -1 -1 10 14 -1 -1 15 -1 -1 3 6 11 -1 -1 12 -1 -1 7 -1 13 -1 -1
*/ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值