zoukankan      html  css  js  c++  java
  • 二叉树的基本操作(顺序二叉树)

    该代码的二叉树结点是数字,采用的是用数组存储,一般使用在空结点较少的情况,使用的时候,一定要清楚二叉树元素在数组中的存储顺序特点,比如左右子树序号有什么特点,怎么由孩子结点的找到双亲节点……

    如果想了解链式存储二叉树,可以参考http://www.cnblogs.com/-beyond/p/6200478.html

    #include<iostream>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    
    const int MAX_TREE_SIZE=100;
    const int Nil=0;
    typedef int TElemType;
    typedef int SqBiTree[MAX_TREE_SIZE];
    
    struct position{
        //按满二叉树计算
        int level,order;
    };
    
    //函数声明
    void show();
    void InitBiTree(SqBiTree T);
    void DestroyBiTree(SqBiTree T);
    void CreateBiTree(SqBiTree T);
    int ClearBiTree(SqBiTree T);
    bool EmptyBiTree(SqBiTree T);
    int BiTreeDepth(SqBiTree T);
    TElemType BiTreeRoot(SqBiTree T);
    TElemType GetValue(SqBiTree T,position e);
    bool Assign(SqBiTree T,position e,TElemType value);
    TElemType Parent(SqBiTree T,TElemType e);
    TElemType LeftChild(SqBiTree T,TElemType e);
    TElemType RightChild(SqBiTree T,TElemType e);
    TElemType LeftSibling(SqBiTree T,TElemType e);
    TElemType RightSibling(SqBiTree T,TElemType e);
    void InsertChild(SqBiTree T,TElemType p,int LR,SqBiTree c);
    void Move(SqBiTree q,int j,SqBiTree T,int i);
    void PreOrderTraverse(SqBiTree T,int i);
    void InOrderTraverse(SqBiTree T,int i);
    void PostOrderTraverse(SqBiTree T,int i);
    void LevelOrderTraverse(SqBiTree T);
    void Print(SqBiTree T);
    
    int main(){
        int x,LR,action;
        position p;
        TElemType e;
        SqBiTree T,s;
        show();
        while(cin>>action){
            switch(action){
            case 1:
                system("cls");
                InitBiTree(T);
                cout<<"初始化二叉树成功"<<endl<<endl;
                break;
            case 2:
                system("cls");
                CreateBiTree(T);
                cout<<"二叉树创建成功"<<endl<<endl;
                break;
            case 3:
                system("cls");
                cout<<"先序遍历二叉树,结果为:"<<endl;
                PreOrderTraverse(T,0);
                cout<<endl<<endl;
                break;
            case 4:
                system("cls");
                cout<<"中序遍历二叉树,结果为:"<<endl;
                InOrderTraverse(T,0);
                cout<<endl<<endl;
                break;
            case 5:
                system("cls");
                cout<<"后序遍历二叉树,结果为:"<<endl;
                PostOrderTraverse(T,0);
                cout<<endl<<endl;
                break;
            case 6:
                system("cls");
                cout<<"层序遍历二叉树,结果为:"<<endl;
                LevelOrderTraverse(T);
                cout<<endl<<endl;
                break;
            case 7:
                system("cls");
                cout<<"请输入层数和序号:"<<endl;
                cin>>p.level>>p.order;
                cout<<"第"<<p.level<<"层"<<" 第"<<p.order<<"个结点的值为: "<<GetValue(T,p);
                cout<<endl<<endl;
                break;
            case 8:
                system("cls");
                ClearBiTree(T);
                cout<<"已清空二叉树"<<endl<<endl;
                break;
            case 9:
                InitBiTree(s);
                cout<<"请输入右子树为空的二叉树s:"<<endl;
                CreateBiTree(s);
                cout<<"待插入的二叉树已经建立,请输入将要插入的结点的值:"<<endl;
                cin>>e;
                cout<<"待插入的二叉树成为左孩子(0),右孩子(1):"<<endl;
                cin>>LR;
                InsertChild(T,e,LR,s);
                cout<<"操作成功"<<endl<<endl;
                break;
            case 10:
                system("cls");
                cout<<"二叉树的各结点为:"<<endl;
                Print(T);
                cout<<endl;
                break;
            case 11:
                system("cls");
                cout<<"请输入双亲结点"<<endl;
                cin>>e;
                cout<<"左孩子结点的值为: "<<LeftChild(T,e)<<endl;
                break;
            case 12:
                system("cls");
                cout<<"请输入双亲结点"<<endl;
                cin>>e;
                cout<<"右孩子结点的值为: "<<RightChild(T,e)<<endl;
                break;
            case 13:
                system("cls");
                cout<<"请输入右兄弟结点"<<endl;
                cin>>e;
                cout<<"左兄弟结点的值为: "<<LeftSibling(T,e)<<endl;
                break;
            case 14:
                system("cls");
                cout<<"请输入左兄弟结点"<<endl;
                cin>>e;
                cout<<"右兄弟结点的值为: "<<RightSibling(T,e)<<endl;
                break;
            case 15:
                system("cls");
                cout<<"请输入孩子结点"<<endl;
                cin>>e;
                cout<<"双亲结点的值为: "<<Parent(T,e)<<endl;
                break;
            case 16:
                system("cls");
                cout<<"二叉树的深度为: "<<BiTreeDepth(T)<<endl;
                break;
            case 17:
                system("cls");
                cout<<"根结点的值为: "<<BiTreeRoot(T)<<endl;
                break;
            case 18:
                system("cls");
                cout<<"请输入结点的层数和在该层的序号: "<<endl;
                cin>>p.level>>p.order;
                cout<<"请输入将赋给该结点的值:"<<endl;
                cin>>e;
                Assign(T,p,e);
                cout<<"赋值成功!"<<endl;
                break;
            }
            system("pause");
            system("cls");
            show();
        }
    
    
    }
    void show(){
        cout<<"+-----------------------------------------------+"<<endl;
        cout<<"|                                               |"<<endl;
        cout<<"|         1->初始化二叉树                       |"<<endl;
        cout<<"|         2->创建二叉树                         |"<<endl;
        cout<<"|         3->先序遍历二叉树                     |"<<endl;
        cout<<"|         4->中序遍历二叉树                     |"<<endl;
        cout<<"|         5->后序遍历二叉树                     |"<<endl;
        cout<<"|         6->层序遍历二叉树                     |"<<endl;
        cout<<"|         7->获取树结点的值                     |"<<endl;
        cout<<"|         8->清空二叉树                         |"<<endl;
        cout<<"|         9->插入二叉树                         |"<<endl;
        cout<<"|        10->打印二叉树                         |"<<endl;
        cout<<"|        11->获取左孩子                         |"<<endl;
        cout<<"|        12->获取右孩子                         |"<<endl;
        cout<<"|        13->获取左兄弟                         |"<<endl;
        cout<<"|        14->获取右兄弟                         |"<<endl;
        cout<<"|        15->获取结点双亲                       |"<<endl;
        cout<<"|        16->获取二叉树深度                     |"<<endl;
        cout<<"|        17->获取根节点                         |"<<endl;
        cout<<"|        18->给结点赋值                         |"<<endl;
        cout<<"+-----------------------------------------------+"<<endl;
    
    }
    
    void InitBiTree(SqBiTree T){
        int i;
        for(i=0;i<MAX_TREE_SIZE;i++){
            T[i]=Nil;//初始值为Nil
        }
    }
    
    void DestroyBiTree(SqBiTree T){
        int i;
        for(i=0;i<MAX_TREE_SIZE;i++){
            T[i]=Nil;//初始值为Nil
        }
    }
    
    void CreateBiTree(SqBiTree T){
        int i=0;
        cout<<"请按层需输入结点的值(数字),0表示空结点,以999结束,结点数<"<<MAX_TREE_SIZE<<":"<<endl;
        while(1){
            cin>>T[i];
            if(T[i]==999){
                T[i]=Nil;
                break;
            }
            i++;
        }
        for(i=1;i<MAX_TREE_SIZE;i++){
            if(i!=0 && T[(i+1)/2-1]==Nil && T[i]!=Nil){
                cout<<"出现无双亲的非根节点!"<<endl;
                break;
            }
        }
    }
    
    int ClearBiTree(SqBiTree T){
        int i;
        for(i=0;i<MAX_TREE_SIZE;i++){
            T[i]=Nil;//初始值为Nil
        }
    }
    
    //判断二叉树是否为空
    bool EmptyBiTree(SqBiTree T){
        if(T[0]==Nil){
            return true;
        } else {
            return false;
        }
    }
    
    //获取二叉树的深度
    int BiTreeDepth(SqBiTree T){
        int i=MAX_TREE_SIZE-1,j=0;
        while(i>=0){
            //从后往前寻找到第一个结点不是默认值的下标
            if(T[i]!=Nil){
                break;
            }
            i--;
        }
        while(i>=pow(2,j)){
            j++;
        }
        return j;
    }
    
    //获取根结点的值
    TElemType BiTreeRoot(SqBiTree T){
        if(EmptyBiTree(T)){
            return Nil;
        } else {
            return T[0];
        }
    }
    
    //获取给定结点e的值
    TElemType GetValue(SqBiTree T,position e){
        return T[int(pow(2,e.level-1)+e.order-2)];
    }
    
    //给结点赋值
    bool Assign(SqBiTree T,position e,TElemType value){
        int i=pow(2,e.level-1)+e.order-2;
        if(value!=Nil && T[(i+1)/2-1]==Nil){
            cout<<"非法操作,禁止给不含双亲的孩子赋非空值"<<endl;
            return false;
        }
        else if(value==Nil && (T[i*2+1]!=Nil || T[i*2+2]!=Nil)){
            cout<<"非法操作,禁止给含有孩子的双亲赋空值"<<endl;
            return false;
        }
        T[i]=value;
        return true;
    }
    
    //获取双亲结点的值
    TElemType Parent(SqBiTree T,TElemType e){
        if(!EmptyBiTree(T)){
            for(int i=0;i<=MAX_TREE_SIZE;i++){
                if(T[i]==e){//判断结点e是否存在与二叉树中
                    return T[(i+1)/2-1];
                }
            }
        } else {
            return Nil;//二叉树为空或者没有结点e
        }
    }
    
    //获取左孩子的值
    TElemType LeftChild(SqBiTree T,TElemType e){
        if(!EmptyBiTree(T)){
            for(int i=0;i<MAX_TREE_SIZE;i++){
                if(T[i]==e){//判断结点e是否存在与二叉树中
                    return T[i*2+1];//返回其左孩子的值
                }
            }
        } else {
            return Nil;//二叉树为空或者没有结点e
        }
    }
    
    //获取右孩子的值
    TElemType RightChild(SqBiTree T,TElemType e){
        if(!EmptyBiTree(T)){
            for(int i=0;i<MAX_TREE_SIZE;i++){
                if(T[i]==e){//判断结点e是否存在与二叉树中
                    return T[i*2+2];//返回其左孩子的值
                }
            }
        } else {
            return Nil;//二叉树为空或者没有结点e
        }
    }
    
    //获取左兄弟的值
    TElemType LeftSibling(SqBiTree T,TElemType e){
         if(!EmptyBiTree(T)){
            for(int i=0;i<MAX_TREE_SIZE;i++){
                if(T[i]==e && i%2==0){//判断结点e是否存在与二叉树中
                    //并且存在有兄弟,i%2=0为右孩子
                    return T[i-1];//返回其左兄弟的值
                }
            }
        } else {
            return Nil;//二叉树为空或者没有结点e
        }
    }
    
    //获取右兄弟的值
    TElemType RightSibling(SqBiTree T,TElemType e){
         if(!EmptyBiTree(T)){
            for(int i=0;i<MAX_TREE_SIZE;i++){
                if(T[i]==e && i%2==1){//判断结点e是否存在与二叉树中
                    //并且存在有兄弟,i%2==1为左孩子
                    return T[i+1];//返回其右兄弟的值
                }
            }
        } else {
            return Nil;//二叉树为空或者没有右兄弟
        }
    }
    //仔细观察,寻找双亲、左右孩子和左右兄弟的方法都类似
    //首先都得判断二叉树是否为空,然后再判断时候该结点是否存在
    //最后根据判断返回结点值
    
    //插入二叉树
    void InsertChild(SqBiTree T,TElemType p,int LR,SqBiTree c){
        //非空二叉树c要插到T中的p结点下面,成为p结点的(左或右)子树
        //非空二叉树c与T无交集,且右子树为空,p结点原有的左或右子树成为s的右子树
        //LR=0 c成为左子树,LR=1 c成为右子树
        int i=0,j,k;
        //查找p结点的序号
        //int temp=int(pow(2,BiTreeDepth(T)));
        //for(j=0;j<temp-1;j++){
        //  if(T[j]==p){
        //      break;
        //  }
        //}
        //或者
        for(j=0;j<MAX_TREE_SIZE;j++){
            if(T[j]==p){
                break;
            }
        }
        k=2*j+1+LR;//k为c子树将要插入的序号
        if(T[k]!=Nil){
            Move(T,k,T,2*k+2);
        }
        Move(c,i,T,k);
    }
    
    //移动二叉树
    void Move(SqBiTree q,int j,SqBiTree T,int i){
        //把从二叉树q的j结点开始的子树 移为 从二叉树T的i结点开始的子树
        if(q[2*j+1]!=Nil){//q的左子树不为空
            Move(q,(2*j+1),T,(2*i+1));
        }
        if(q[2*j+2]!=Nil){//q的右子树不为空
            Move(q,(2*j+2),T,(2*i+2));
        }
        T[i]=q[j];
        q[i]=Nil;
    }
    
    //先序遍历
    void PreOrderTraverse(SqBiTree T,int i){
        cout<<T[i]<<' ';
        if(T[2*i+1]!=Nil){
            PreOrderTraverse(T,2*i+1);
        }
        if(T[2*i+2]!=Nil){
            PreOrderTraverse(T,2*i+2);
        }
    }
    
    //中序遍历
    void InOrderTraverse(SqBiTree T,int i){
        if(T[2*i+1]!=Nil){
            InOrderTraverse(T,2*i+1);
        }
        cout<<T[i]<<' ';
        if(T[2*i+2]!=Nil){
            InOrderTraverse(T,2*i+2);
        }
    }
    
    //后序遍历
    void PostOrderTraverse(SqBiTree T,int i){
        if(T[2*i+1]!=Nil){
            PostOrderTraverse(T,2*i+1);
        }
        if(T[2*i+2]!=Nil){
            PostOrderTraverse(T,2*i+2);
        }
        cout<<T[i]<<' ';
    }
    
    //层序遍历
    void LevelOrderTraverse(SqBiTree T){
        int i=MAX_TREE_SIZE-1;
        while(T[i]==Nil){
            i--;
        }
        for(int j=0;j<=i;j++){
            if(T[j]!=Nil){
                cout<<T[j]<<' ';
            }
        }
        cout<<endl;
    }
    
    //逐层按本层序号输出二叉树
    void Print(SqBiTree T){
        int j,k;
        position p;
        TElemType e;
        for(j=1;j<=BiTreeDepth(T);j++){
            cout<<"第"<<j<<"层: ";
            for(k=1;k<=pow(2,j-1);k++){
                p.level=j;
                p.order=k;
                e=GetValue(T,p);
                cout<<k<<":"<<e<<"     ";
            }
            cout<<endl;
        }
        cout<<endl;
    }
    

      

  • 相关阅读:
    在Excel中查找/替换时使用换行符
    用fieldset标签轻松实现Tab选项卡效果
    用JSFL将Flash中的元件导出为PNG
    PHP学习笔记之PDO
    网页中的数学公式
    解决fl.findObjectInDocByType/fl.findObjectInDocByName的毛病
    HTML+CSS 网页中鼠标滚轮失效的解决办法
    jQuery 离开页面时提示
    ASP 计算出指定年份生肖
    au3创建Access数据库表例子
  • 原文地址:https://www.cnblogs.com/-beyond/p/6065189.html
Copyright © 2011-2022 走看看