4-14 还原二叉树 (15 分)

这篇博客讨论了如何根据先序和中序遍历序列来还原二叉树并计算其高度。作者分享了尝试过程中遇到的错误,即在递归调用时从1开始而非0,修正后成功解决问题。此外,还提到了一种不建树直接通过递归求树高的方法。
摘要由CSDN通过智能技术生成

4-14 还原二叉树 (15 分)
给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。

输入格式:
输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。

输出格式:
输出为一个整数,即该二叉树的高度。

输入样例:
9
ABDFGHIEC
FDHGIBEAC
结尾无空行
输出样例:
5
我用的书上的方法写的错误代码

#include<stdio.h>
typedef char datatype;
typedef struct bitnode
{
    datatype data;
    struct bitnode*lchild,*rchild;
}BiTNode,*BiTree;
BiTree Initiate();//二叉树初始化
BiTree Initiate()
{
  BiTNode *bt;
  bt=(BiTNode*)malloc(sizeof(BiTNode));
  bt->lchild=NULL;
  bt->rchild=NULL;
  return bt;
}
void ReBiTree(char preod[],char inod[],int n,BiTree*root);
void ReBiTree(char preod[],char inod[],int n,BiTree*root)
{
    if(n<=0)*root=NULL;
    else
        PreInOd(preod,1,n,inod,1,n,root);
}
void PreInOd(char preod[],int i,int j,char inod[],int k,int h,BiTree *t);
void PreInOd(char preod[],int i,int j,char inod[],int k,int h,BiTree *t)
{
    int m;
    *t=(BiTNode*)malloc(sizeof(BiTNode));
    (*t)->data=preod[i];
    m=k;
    while(inod[m]!=preod[i])
        m++;
    if(m==k)(*t)->lchild=NULL;
    else
        PreInOd(preod,i+1,i+m-k,inod,k,m-1,&((*t)->lchild));
    if(m==h)(*t)->rchild=NULL;
    else
        PreInOd(preod,i+m-k+1,j,inod,m+1,h,&((*t)->rchild));
}
void PrintTree(BiTree t);
void PrintTree(BiTree t)
{
    if(t==NULL)return ;
    PrintTree(t->lchild);
PrintTree(t->rchild);
    printf("%c",t->data);
}
int main()
{
    int n;
    scanf("%d",&n);
    datatype str1[n];
    datatype str2[n];
    scanf("%s%s",str1,str2);
    BiTree t=(BiTree)malloc(sizeof(BiTNode));
    ReBiTree(str1,str2,n,&t);
    printf("1");
    PrintTree(t);

}

正确代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node{
    char elem;
    struct node *left,*right;
};
typedef struct node * Tree;
char in[55],pre[55];
Tree findTree(char in[],char pre[],int length){//根据中序,先序建树
    if(length==0) return NULL;
    Tree head=(Tree)malloc(sizeof(struct node));
    head->elem=pre[0];
    int i=0;
    for(i=0;i<length;i++){
        if(in[i]==pre[0]) break;//找分界点
    }
    head->left=findTree(in,pre+1,i);//他这是直接用数组的位置表示的开始下标,再用个长度就可以表示结尾位置了
    head->right=findTree(in+i+1,pre+i+1,length-i-1);
    return head;
}
int length(Tree head){
    if(head==NULL) return 0;
    int l=length(head->left);
    int r=length(head->right);
    return l>r?l+1:r+1;
}
int main(){
    int n;
    scanf("%d",&n);
    scanf("%s%s",pre,in);
    Tree head=(Tree)malloc(sizeof(struct node));
    head=findTree(in,pre,n);
    printf("%d\n",length(head));
return 0;
}

唉,我能看懂,就是写不出来,思路也清楚
不知道哪里出错了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node{
    char elem;
    struct node *left,*right;
};
typedef struct node * Tree;
char in[55],pre[55];
Tree PreInOd(char pre[],int i,int j,char in[],int k,int h);//书上的函数哦
Tree PreInOd(char pre[],int i,int j,char in[],int k,int h)
{
    if((j-i)<=0)return NULL;

      Tree head=(Tree)malloc(sizeof(struct node));
    head->elem=pre[0];
    int m=k;
    printf("hahah");
    while(in[m]!=pre[i])
        m++;
        printf("laa");

      head->left=PreInOd(pre,i+1,i+m-k,in,k,m-1);

        head->right=PreInOd(pre,i+m-k+1,j,in,m+1,h);
    return head;


}
/*Tree findTree(char in[],char pre[],int length){
    if(length==0) return NULL;
    Tree head=(Tree)malloc(sizeof(struct node));
    head->elem=pre[0];
    int i=0;
    for(i=0;i<length;i++){
        if(in[i]==pre[0]) break;
    }
    head->left=findTree(in,pre+1,i);
    head->right=findTree(in+i+1,pre+i+1,length-i-1);
    return head;
}*/
int length(Tree head){
    if(head==NULL) return 0;
    int l=length(head->left);
    int r=length(head->right);
    return l>r?l+1:r+1;
}
void printTree(Tree t);
void printTree(Tree t)
{
   if(t==NULL)return ;
    printf("%c",t->elem);
    printTree(t->left);
    printTree(t->right);
}
int main(){
    int n;
    scanf("%d",&n);
    scanf("%s%s",pre,in);
    Tree head=(Tree)malloc(sizeof(struct node));
//    head=findTree(in,pre,n);
head=PreInOd(pre,1,n,in,1,n);
    printTree(head);
    printf("\n");
    printf("%d\n",length(head));
return 0;
}

耶!写出来了,就是在递归调用的时候它的起始应该是从0开始,但我写的都是从1开始,改了就OK了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node{
    char elem;
    struct node *left,*right;
};
typedef struct node * Tree;
char in[55],pre[55];
Tree PreInOd(char pre[],int i,int j,char in[],int k,int h);
Tree PreInOd(char pre[],int i,int j,char in[],int k,int h)
{
    if((j-i)<0)return NULL;

      Tree head=(Tree)malloc(sizeof(struct node));
    head->elem=pre[i];
    int m=k;

    while(in[m]!=pre[i])
       {
          m++;
       }




      head->left=PreInOd(pre,i+1,i+m-k,in,k,m-1);

        head->right=PreInOd(pre,i+m-k+1,j,in,m+1,h);
    return head;


}

int length(Tree head){
    if(head==NULL) return 0;
    int l=length(head->left);
    int r=length(head->right);
    return l>r?l+1:r+1;
}
void printTree(Tree t);
void printTree(Tree t)
{
   if(t==NULL)return ;
    printf("%c",t->elem);
    printTree(t->left);
    printTree(t->right);
}
int main(){
    int n;
    scanf("%d",&n);
    scanf("%s%s",pre,in);
    Tree head=(Tree)malloc(sizeof(struct node));
//    head=findTree(in,pre,n);
head=PreInOd(pre,0,n,in,0,n);
    printTree(head);
    printf("\n");
    printf("%d\n",length(head));
return 0;
}

还有一种方法就是不用建树,直接用那个求树高递归,它本来求树高的程序如下

int length(Tree head){
    if(head==NULL) return 0;
    int l=length(head->left);
    int r=length(head->right);
    return l>r?l+1:r+1;
}

这个是直接在已建好树的情况下去递归求树高,还可以直接递归

#include <stdio.h>

int max(int a,int b){
    return a>b?a:b;
}

int Depth(char* pre,char* in,int n);//求给定先序和中序序列对应的树的高度

int main()
{
    int n;//声明变量存储树的节点个数.
    scanf("%d",&n);
    char pre[n+1],in[n+1];  //声明字符数组分别存储先序和中序遍历序列
    scanf("%s",pre);//读入先序序列
    scanf("%s",in);//读入中序序列
    printf("%d",Depth(pre,in,n));//输出先序和中序序列对应的树的高度
    return 0;
}

int Depth(char* pre,char* in,int n)   //pre:先序序列;   in:中序序列;    n:节点个数;
{
    int left,right,i;
    if(n == 0)    //若没有结点,为空树
    {
        return 0;
    }
    for(i = 0; i < n; i++)
    {
        if(in[i] == pre[0])  //找到根结点在中序的位置
        {
            break;
        }
    }
    left = Depth(pre+1,in,i);  //左子树的深度
    right = Depth(pre+i+1,in+i+1,n-i-1);   //右子树的深度
    return max(left,right)+1;  //返回左右子树深度的较大值中的较大值+根结点
}
还原二叉树是指根据二叉树的前序遍历和中序遍历结果,重建出原二叉树的过程。实现这个过程的关键是找到二叉树的根节点,然后再根据根节点将左子树和右子树递归地还原。 首先,我们需要定义一个二叉树节点的类,包含节点值、左孩子节点和右孩子节点的属性。接下来,我们可以使用递归的方法来还原二叉树。 我们可以利用前序遍历的结果,找到二叉树的根节点。前序遍历结果的第一个元素就是根节点的值。然后,我们可以在中序遍历结果中找到根节点的位置,将中序遍历结果为左子树和右子树的部。 接下来,对于根节点的左子树,我们可以用前序遍历结果和中序遍历结果的左子树部递归地还原左子树。同理,对于根节点的右子树,我们可以用前序遍历结果和中序遍历结果的右子树部递归地还原右子树。 最后,我们将根节点的左子树和右子树连接到根节点上,就可以得到还原后的二叉树。 下面是一个简单的Python代码实现还原二叉树的过程: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(preorder, inorder): if not preorder or not inorder: return None # 根据前序遍历结果找到根节点 root_val = preorder[0] root = TreeNode(root_val) # 在中序遍历结果中找到根节点的位置,将左子树和右子树开 root_index = inorder.index(root_val) left_inorder = inorder[:root_index] right_inorder = inorder[root_index+1:] # 递归还原左子树和右子树 left_preorder = preorder[1:1+len(left_inorder)] right_preorder = preorder[1+len(left_inorder):] root.left = buildTree(left_preorder, left_inorder) root.right = buildTree(right_preorder, right_inorder) return root # 测试 preorder = [1, 2, 4, 5, 3, 6, 7] inorder = [4, 2, 5, 1, 6, 3, 7] root = buildTree(preorder, inorder) ``` 以上是还原二叉树的简单实现。这个方法的时间复杂度为O(n),其中n是二叉树节点的个数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值