二叉树由前序,中序遍历输出后序遍历(纯代码,自己写的和网上搜的标准的写法)

博客作者分享了自己编写二叉树前序、中序遍历得到后序遍历的算法,并对比了自己与网上的标准实现。讨论了如何仅通过前序、中序遍历的字符串和长度来重建二叉树,强调在递归过程中如何确定子节点的前后序遍历起始位置。
摘要由CSDN通过智能技术生成

心情:

这几天又颓了几天,又开始追剧。。。果然我还是那么没有自制力,慢慢改。。。

关于这个二叉树典型的算法,我其实一直没看过什么标准答案,我都是自己写的,比如今天的:

#include<string>
#include<iostream>

using namespace std;

typedef struct TreeNode{

    char c;
    struct TreeNode *left;
    struct TreeNode *right;

}TreeNode;


TreeNode* buildTree(string a,string b,int &astart,int bstart,int bend){


    TreeNode *q=new TreeNode;
    q->c=a[astart];

    if(bstart==bend){
        q->left=NULL;
        q->right=NULL;
        return q;
    }

    if(bstart>bend){
        astart--;
        return NULL;
    }

    int i=bstart;
    while(b[i]!=a[astart]) i++;

    q->left=buildTree(a,b,++astart,bstart,i-1);
    q->right=buildTree(a,b,++astart,i+1,bend);

    return q;

}

void PostOrder(TreeNode *root){

    if(!root){
        return;
    }

    PostOrder(root->left);
    PostOrder(root->right);
    cout<<root->c;
}

int main(){

    string a;
    string b;

    cin>>a;
    cin>>b;

    int lena=a.size();

    int astart=0;
    TreeNode *root=buildTree(a,b,astart,0,lena-1);

    PostOrder(root);

}

中途改了很多次,这让我开始慌了,如果真的上机是这种题目,其实心中有一个标准版本还是比较好一点。

在网上搜的标准的

链接:https://www.nowcoder.com/questionTerminal/6e732a9632bc4d12b442469aed7fe9ce
来源:牛客网

#include <iostream>
#include <cstring>
using namespace std;
 
 
 
typedef struct BinaryTree
    {
    char data;
    BinaryTree* lchild;
    BinaryTree* rchild;
}BinaryTree;
 
void RebuildTree(BinaryTree* &Tree,char* pre,char* in,int len)
    {
    Tree = (BinaryTree*)malloc(sizeof(BinaryTree));
    if(Tree!=NULL)
        {
        if(len<=0)
            {//递归截止条件
            Tree = NULL;
            return ;
        }
        int index = 0;
        while(index<len&&*(pre)!=*(in+index))
            {//寻找当前的root结点(包含子树)
            index++;
        }
        Tree->data = *(pre);
        RebuildTree(Tree->lchild,pre+1,in,index);//去掉root结点
        RebuildTree(Tree->rchild,pre+1+index,in+1+index,len-(index+1));//去掉左边和根节点
    }
    return ;
}
 
void PostOrderTravese(BinaryTree* Tree)
    {//后序遍历输出
    if(Tree==NULL)
        return;
    PostOrderTravese(Tree->lchild);
    PostOrderTravese(Tree->rchild);
    printf("%c",Tree->data);
}
 
 
int main()
{
    char pre[101];
    char in[101];
    while(scanf("%s %s",pre,in)!=EOF)
        {
        BinaryTree* tree;
        int length = strlen(pre);
        RebuildTree(tree,pre,in,length);   
        PostOrderTravese(tree);
        cout<<endl;
    }
    return 0;
}

并不是说这个代码最简洁,但是在函数的参数方面应该是标准的
RebuildTree(tree,pre,in,length)
1.只需要两个字符串,一个长度,比我的简单多了,判断为空直接length==0
2.递归的部分
RebuildTree(Tree->lchild,pre+1,in,index);
RebuildTree(Tree->rchild,pre+1+index,in+1+index,len-(index+1));
第一个很明显在递归左边时,只需要前序遍历的下一个字符
第二个在递归第二个是,需要的是当前节点除去左边节点和当前节点值的第一个,长度自然也是减去当前节点和左边的值

好了!下次打的时候可以参考了,一个长度,两个支付穿指针搞定一切!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值