已知一颗二叉树的后序遍历序列和中序遍历序列,写出可以确定这颗二叉树的算法

已知一棵二叉树的后序遍历序列和中序遍历序列,写出可以确定这棵二叉树的算法。

输入

dabec# //后序序列,其中#代表结束符
debac# //中序序列,其中#代表结束符
输出

ce0db00000a0000 //满二叉树形式输出(就是按照从上到下,从左到右的形式输出一颗满二叉树)

输入输出样例:1组

#1

  • 样例输入:
    dabec# //后序序列,其中#代表结束符
    debac# //中序序列,其中#代表结束符
  • 样例输出:
    ce0db00000a0000 //满二叉树形式输出

    参考代码:

    #include 
    #include 
    #include 
    #include 
    #define MAX 100
    
    typedef struct tree
    {
        char data;
        struct tree *lchild , *rchild;
    } BinNode,*BiTree;
    
    BiTree restore(char* zhong, char *hou, int length)
    {//后序中序恢复二叉树
        if(length == 0)
        {
            return NULL;
        }
        BiTree node;
        node = (BinNode *)malloc(sizeof(BinNode));
        node->data= *(hou+length-1);
        int rootIndex = 0;
        for(;rootIndex < length; rootIndex++)
        {
            if(zhong[rootIndex] == *(hou+length-1))
                break;
        }
        node->lchild = restore(zhong, hou , rootIndex);
        node->rchild = restore(zhong + rootIndex + 1, hou + rootIndex , length - (rootIndex + 1));
        //中序中根节点右边的点,在后序中也一定在后边
        return node;
    }
    int Height_tree(BiTree T)
    {//获得当前树的高度
        int r,l;
        if (T == NULL){
            return 0;
        }
        l = Height_tree(T->lchild);
        r = Height_tree(T->rchild);
        return l>=r?l+1:r+1;
    }
    
    void Levelorder(BiTree T, BinNode *queue[],char c[],int height)
    {//层次遍历输出满二叉树,T代表树的根,queue代表层次队列,c是输出的序列(从1开始存储),height是代表树的高度
        BinNode *p;
        int front,rear;
        int i =1;
        if(T == NULL){
                return;
    
        }
        rear = 0;
        front = -1;
        queue[rear] = T;
        c[1] = T->data;
        while(front != rear){ //只要队列不空
            front++; //准备出队
            if(queue[front]==NULL)//如果当前队列出队为空,则将其左右空孩子都入队,并且放入输出数组中
             {
                 c[++i]='0';
                 c[++i]='0';
                 rear++;
                 queue[rear]=NULL;
                 rear++;
                 queue[rear]=NULL;
                 continue;
             }
             if(i>=pow(2,height)) break; //如果i的值比2^height都多,证明已经是最后了。
             i++;
             if(queue[front]->lchild!=NULL){ //如果当前结点的左孩子不空,则入队,并且将其装入输出队列中
                rear++;
                queue[rear] = queue[front]->lchild;
                c[i] = queue[rear]->data;
            }
            else{//否则,当前节点没有左孩子的话,则入队‘0’并且入队空指针
                 c[i] = '0';
                 rear++;
                 queue[rear]=NULL;
            }
            i++;
            if(queue[front]->rchild!=NULL){//层次遍历,先左后右。如果当前节点的右孩子不空,则入队,并且将其装入输出队列中
                rear++;
                queue[rear] = queue[front]->rchild;
                c[i]  =queue[rear]->data;
            }
            else{//否则,当前节点没有右孩子的话,则入队'0'并且入队空指针
              c[i] = '0';
              rear++;
              queue[rear]=NULL;
            }
        }
        for(i = 1;i

     利用数组实现:

    #include 
    #include 
    #include 
    #include 
    #define MAX 100
    typedef char bt_type;
    // build by postorder and inorder sequence(data must be unique)
    void BuildBinTree(bt_type *T, int m, bt_type postOrder[], int postL,
                         bt_type inOrder[], int inL, int n)
    {
      if (n == 0)
        return;
      int i;
      for (i = 0; i < n && inOrder[inL + i] != postOrder[postL + n - 1]; ++i)
        ;
      int numL = i, numR = n - i - 1;
      T[m]= postOrder[postL + n - 1];
      BuildBinTree(T, m*2, postOrder, postL, inOrder, inL, numL);
      BuildBinTree(T, m*2+1, postOrder, postL + numL, inOrder,
                              inL + numL + 1, numR);
    }
    int GetHeight(bt_type *T, int m)
    {
      int h1, h2;
      if (T[m] != 0)
      {
        h1 = GetHeight(T, m * 2);
        h2 = GetHeight(T, m * 2 + 1);
        return (h1 > h2 ? h1 : h2) + 1;
      }
      return 0;
    }
    int main()
    {
      bt_type postOrder[MAX], inOrder[MAX], T[MAX] = {0};
      int n, i;
      scanf("%s%s", postOrder, inOrder);
      n = strlen(postOrder) - 1;
      BuildBinTree(T, 1, postOrder, 0, inOrder, 0, n);
      int height = GetHeight(T, 1);
      int max = pow(2, height) - 1;
      for (i = 1; i <= max; ++i)
        printf("%c", T[i]!=0?T[i]:'0');
      return 0;
    }
    

     

    数据结构初学,下面是自己写的代码,复杂度高且耗内存,不推荐。 

    #include 
    #include 
    #include 
    #define max 20
    typedef struct bitnode
    {
        char data;
        struct bitnode *left,*right;
        int parent;
    } BitNode,*BiTree;
    BiTree init()
    {
        BitNode *bt;
        //bt=(BiTree)malloc(sizeof(BitNode));
        bt=NULL;
        return bt;
    }
    int cout=1;
    void recover(char preod[],int i,int j,char inod[],int k,int h,BiTree *bt,int len)//preod是后序序列,inod是中序序列
    {
        int m;
        (*bt)=(BitNode*)malloc(sizeof(BitNode));
        (*bt)->data=preod[j];//将根节点赋值
        m=k;
        while(inod[m]!=preod[j])
            m++;
        if(m==k)
        {
            (*bt)->left=NULL;
        }
        else recover(preod,i,i+m-k-1,inod,k,m-1,&((*bt)->left),len);
        if(m==h)
        {
            (*bt)->right=NULL;
        }
        else recover(preod,m-k,j-1,inod,m+1,h,&((*bt)->right),len);
    }
    BitNode *rebitree(char preod[],char inod[],BiTree bt,int len)
    {
        if(len<0) bt=NULL;
        else recover(preod,0,len-1,inod,0,len-1,&bt,len);
        return bt;
    }
    int depth(BiTree bt)//一级指针,计算叶子结点的个数
    {
        int countle=0,countr=0;
        if(bt==NULL) return 0;//为空树
        else
        {
            countle++;
            countr++;
            countle+=depth(bt->left);//左子树层数
            countr+=depth(bt->right);//右子树层数
            return  countle>countr?countle:countr;
        }
    }
    void order(BiTree *bt,int dep)//dep为树的深度
    {
        int s;
        BitNode *queue[max];
        for(s=0; sparent=-2;
        while(front!=rear&&rear<=pow(2.0,dep)-2)
        {
            front++;
            if(queue[front]->data!='0')
            {
                if(queue[front]->left!=NULL&&queue[front]->data!='0')
                {
                    rear++;
                    queue[rear]=queue[front]->left;
                }
                if(queue[front]->left==NULL)
                {
                    rear++;
                    queue[rear]->data='0';
                    if(rearrear+1)
                                break;
                        }
                        int k=cout;
                        int t=rear;
                        for(i=1; i<=dep-k; i++)
                        {
                            t=2*t+1;
                            queue[t]->data='0';
                            for(j=1; jdata='0';
                            }
                        }
                    }
                }
                if(queue[front]->right!=NULL&&queue[front]->data!='0')
                {
                    rear++;
                    queue[rear]=queue[front]->right;
                }
                if(queue[front]->right==NULL)
                {
                    rear++;
                    queue[rear]->data='0';
                    if(rearrear+1)
                                break;
                        }
                        int k=cout;
                        int t=rear;
                        for(i=1; i<=dep-k; i++)//实现该以及其子树底结点赋值为0
                        {
                            t=2*t+1;
                            queue[t]->data='0';
                            for(j=1; jdata='0';
                            }
                        }
                    }
                }
            }
            else
            {
                if(reardata);
    }
    int main()
    {
        BitNode *bt;
        bt=init();
        char preod[max],inod[max];
        char ch;
        int depcout=0;
        int len1=0,len2=0;
        do
        {
            scanf("%c",&ch);
            preod[len1]=ch;
            len1++;
        }
        while(ch!='#');
        getchar();
        do
        {
            scanf("%c",&ch);
            inod[len2]=ch;
            len2++;
        }
        while(ch!='#');
        bt=rebitree(preod,inod,bt,len1-1);//恢复二叉树,输入后序,中序序列
        depcout=depth(bt);//求取树的深度
        order(&bt,depcout);//实现满二叉树的输出
        return 0;
    }
    

     

你可能感兴趣的:(数据结构,二叉树)