根据先序中序(或者中序后序)建立树,并且输出层序序列

主要我觉得可以分为三大板块,写三个函数就可以搞定这个问题,所以说这个不难,但对于初学者来说,一定要克服心里的障碍,不要害怕,嘿嘿,因为这也是我之前的真实想法。

定义树结构体

struct node{     //定义结构体建立树节点
int data;
node* lchild;
node* rchild;
};
int pre[maxn],in[maxn],post[maxn]; //存放先序,中序,后续的数组

先序和中序建立树

node* creaprein(int prel,int prer,int inl,int inr) //先序和中序建立树
{
    if(prel>prer) return NULL; //递归边界,长度小于等于0,直接返回
    node* root=new node;       //建立新节点,存放根节点
    root->data=pre[prel];      //根节点的数据域是根节点的值
    int i;                      
    for(i=inl;i<=inr;i++)
    {
         if(in[i]==pre[prel])  //找到该节点,并记录下标值
            break;
    }
    int num=i-inl; 
    root->lchild=creaprein(prel+1,prel+num,inl,i-1);  //递归其左子树
    root->rchild=creaprein(prel+num+1,prer,i+1,inr);  //递归其右子树
    return root;      //递归终点,返回根节点
}

中序和后序建立树

node* creainpost(int postl,int postr,int inl,int inr) //中序和后序建立树
{  
    if(postl>postr) return NULL;    //递归边界
    node* root=new node;
    root->data=post[postr];   //先序和后序不同的就在于这里
    int i;
    for(i=inl;i<=inr;i++)
    {
        if(in[i]==post[postr])
            break;
    }
    int num=i-inl;
    root->lchild=creainpost(postl,postl+num-1,inl,i-1);//递归其左子树
    root->rchild=creainpost(postl+num,postr-1,i+1,inr);//递归其右子树
    return root;
}

层序输出

void prin(node* root)  //层序遍历输出
{
    queue<node*> q;   //建立队列,并且这是node型指针
    q.push(root);   //压入根节点
    while(!q.empty())  //判断队列是否为空,从而结束循环
    {
        node* now=new node;
        now=q.front();    //建立新节点并且取出队列首元素,取出不是删除,类似一个把队首元素赋值的意思
        cout<<now->data<<' ';   //输出队首元素的值
        q.pop();    //输出完之后就可以pop掉队首元素
        if(now->lchild!=NULL)   //但是此时的now依旧存在 判断他是否有左孩子 
        q.push(now->lchild);   //递归左孩子
        if(now->rchild!=NULL)
        q.push(now->rchild);   //递归右孩子
    }
}

最后代码(中序和后序写的)

#include <iostream>
#include <math.h>
#include <stdlib.h>
#include<algorithm>
#include<string>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<queue>
using namespace std;
struct node{     //定义结构体建立树节点
int data;
node* lchild;
node* rchild;
};
int pre[maxn],in[maxn],post[maxn]; //存放先序,中序,后续的数组
node* creaprein(int prel,int prer,int inl,int inr) //先序和中序建立树
{
    if(prel>prer) return NULL; //递归边界,长度小于等于0,直接返回
    node* root=new node;       //建立新节点,存放根节点
    root->data=pre[prel];      //根节点的数据域是根节点的值
    int i;                      
    for(i=inl;i<=inr;i++)
    {
         if(in[i]==pre[prel])  //找到该节点,并记录下标值
            break;
    }
    int num=i-inl; 
    root->lchild=creaprein(prel+1,prel+num,inl,i-1);  //递归其左子树
    root->rchild=creaprein(prel+num+1,prer,i+1,inr);  //递归其右子树
    return root;      //递归终点,返回根节点
}
node* creainpost(int postl,int postr,int inl,int inr) //中序和后序建立树
{  
    if(postl>postr) return NULL;    //递归边界
    node* root=new node;
    root->data=post[postr];   //先序和后序不同的就在于这里
    int i;
    for(i=inl;i<=inr;i++)
    {
        if(in[i]==post[postr])
            break;
    }
    int num=i-inl;
    root->lchild=creainpost(postl,postl+num-1,inl,i-1);//递归其左子树
    root->rchild=creainpost(postl+num,postr-1,i+1,inr);//递归其右子树
    return root;
}
void prin(node* root)  //层序遍历输出
{
    queue<node*> q;   //建立队列,并且这是node型指针
    q.push(root);   //压入根节点
    while(!q.empty())  //判断队列是否为空,从而结束循环
    {
        node* now=new node;
        now=q.front();    //建立新节点并且取出队列首元素,取出不是删除,类似一个把队首元素赋值的意思
        cout<<now->data<<' ';   //输出队首元素的值
        q.pop();    //输出完之后就可以pop掉队首元素
        if(now->lchild!=NULL)   //但是此时的now依旧存在 判断他是否有左孩子 
        q.push(now->lchild);   //递归左孩子
        if(now->rchild!=NULL)
        q.push(now->rchild);   //递归右孩子
    }
}
int main()
{
    int n;    //树的节点个数
    cin>>n;
    for(int i=0;i<n;i++)   //输入中序遍历
        cin>>in[i];
    for(int i=0;i<n;i++)
        cin>>post[i];     //输入后序遍历
    node* root=creainpost(0,n-1,0,n-1);  //利用函数返回根节点
    prin(root);   //打印层序序列
    return 0;
}

你们可以尝试自己写一下先序和中序建立树

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,给定二叉树层序遍历和中序遍历,我们可以通过重建二叉树的方式来得到先序遍历和后序遍历序列。 先用中序遍历的结果确定根节点,然后在层序遍历中找到根节点,将层序遍历结果分为左子和右子。重复以上步骤,直到所有节点都添加到中。 最后,我们可以通过深度优先搜索的方式得到先序遍历和后序遍历序列。 以下是代码实现: ```python from collections import deque class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(inorder, levelorder): if not inorder: return None # 根节点 root = TreeNode(levelorder[0]) index = inorder.index(root.val) # 左子中序遍历结果 left_inorder = inorder[:index] # 右子中序遍历结果 right_inorder = inorder[index+1:] # 左子层序遍历结果 left_levelorder = [x for x in levelorder if x in left_inorder] # 右子层序遍历结果 right_levelorder = [x for x in levelorder if x in right_inorder] # 递归构建左子和右子 root.left = buildTree(left_inorder, left_levelorder) root.right = buildTree(right_inorder, right_levelorder) return root def preorderTraversal(root): if not root: return [] return [root.val] + preorderTraversal(root.left) + preorderTraversal(root.right) def postorderTraversal(root): if not root: return [] return postorderTraversal(root.left) + postorderTraversal(root.right) + [root.val] inorder = [9, 3, 15, 20, 7] levelorder = [3, 9, 20, 15, 7] root = buildTree(inorder, levelorder) preorder = preorderTraversal(root) postorder = postorderTraversal(root) print("先序遍历序列:", preorder) print("后序遍历序列:", postorder) ``` 输出结果为: ``` 先序遍历序列: [3, 9, 20, 15, 7] 后序遍历序列: [9, 15, 7, 20, 3] ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值