前序+中序 = 二叉树(先序、中序、后序、层次遍历)

内心OS:我靠啊!!!我就是偷了一下!!!把先序遍历的代码COPY了两份,改成了中序和后序遍历。万万没想到啊!我忘了修改函数中递归函数的名字!!!找这个BUG花了我三个小时~~我哭啊~~,我还以为我的知识体系坍塌了呢?!!~

总结,这是一道模板题,要先记住大体流程,然后反复练习。

输入格式:

第一行给出结点个数 N(1<=N<= 50)

第二行给出先序序列,共N个整数

第三行给出后序序列,共N个整数

输出格式:

第一行给出先序遍历结果;

第二行给出中序遍历结果;

第三行给出后续遍历结果;

第四行给出层次遍历结果。

输入样例:

7
4 1 3 2 6 5 7
1 2 3 4 5 6 7

输出样例:

4 1 3 2 6 5 7
1 2 3 4 5 6 7
2 3 1 5 7 6 4
4 1 6 3 5 7 2

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;

const int maxn = 100;
int pre[maxn],in[maxn];//先序、中序
int n;                //结点个数
struct Node {
    int data;
    Node* lchild;
    Node* rchild;
};

//当前二叉树的 先序区间[preL,preR], 后序区间[inL,inR]
Node* create(int preL,int preR,int inL,int inR) {
    //第一步,确定递归边界
    if(preL > preR)     return NULL;
    //第二步,保存当前根结点
    Node* root = new Node;
    root->data = pre[preL];
    //第三步,用根结点划分中序
    int k,leftNum;
    for(k = inL; k <= inR; ++k)
        if(in[k] == pre[preL]) break;
    leftNum = k - inL;//当前根节点左子树的结点个数
    //第四步,确定左子树的后序、中序, 右子树的后序,中序
    root->lchild = create(preL+1,preL+leftNum,inL,k-1);
    root->rchild = create(preL+leftNum+1,preR,k+1,inR);
    return root;
}

int num = 0;         //已经访问结点个数
//先序遍历二叉树
void preorder(Node* root) {
    if(root == NULL) return ;//递归边界
    if(num > 0) printf(" ");
    cout<<root->data;
    num++;
    preorder(root->lchild);//访问左子树,两个选择分支
    preorder(root->rchild);//访问右子树
}
//中序遍历二叉树
void inorder(Node* root) {
    if(root == NULL) return ;//递归边界
    inorder(root->lchild);//访问左子树,两个选择分支
    if(num > 0) printf(" ");
    cout<<root->data;
    num++;
    inorder(root->rchild);//访问右子树
}
//后序序遍历二叉树
void postorder(Node* root) {
    if(root == NULL) return ;//递归边界
    postorder(root->lchild);//访问左子树,两个选择分支
    postorder(root->rchild);//访问右子树
    if(num > 0) printf(" ");
    cout<<root->data;
    num++;
}
//层次遍历
void BFS(Node *root) {
    queue<Node*> que;//第一步,定义队列,结点入队
    que.push(root);
    while(!que.empty()) { //第二步,队列非空
        Node* top = que.front();//第三步,访问队头元素,并出队
        que.pop();
        if(num > 0) printf(" ");
        cout<<top->data;
        num++;
        //第四步,下一层元素入队(左、右孩子入队)
        if(top->lchild != NULL) que.push(top->lchild);
        if(top->rchild != NULL) que.push(top->rchild);
    }
}
int main() {
    cin>>n;
    for(int i = 0; i < n; ++i)
        cin>>pre[i];
    for(int i = 0; i < n; ++i)
        cin>>in[i];
    Node* root = create(0,n-1,0,n-1);//先序+中序重建二叉树
    preorder(root);//先序遍历
    printf("\n");
    num = 0;
    inorder(root);//中序遍历
    printf("\n");
    num = 0;
    postorder(root);//后序遍历
    printf("\n");
    num = 0;
    BFS(root);    //层次遍历
    return 0;
}

原文地址:https://www.cnblogs.com/keep23456/p/12380996.html

时间: 2024-08-05 02:46:37

前序+中序 = 二叉树(先序、中序、后序、层次遍历)的相关文章

二叉树的前中后以及层次遍历

#include "stdio.h" #include "malloc.h" #define datatype char  typedef struct bT { datatypedata; struct bT *lt,*rt; }* bitree,BiNode; void preExCreate(bitree bt); /*递归实现*/ void FprePost(bitree bt) { if(bt) { printf("%c",bt->

递归非递归的二叉树遍历(递归前中后,非递归前中后,层次遍历,凹入打印法等)

由于所有的递归算法都可以借助于堆栈转换成循环结构的非递归算法.方法一:形式化模拟转换.方法二:根据要求解问题的特点设计借助于堆栈的循环结构算法.而此次正好是利用第二种按方法求解. 1.1非递归前序遍历: 首先利用下图来设计非递归前序遍历算法思想: 堆栈结构体如下: #define size 100 typedef struct { DataType data[size]; int tag[100]; //这个是在非递归后序中用到 int top : }SeqStack : (1)初始化设置一个堆

二叉树前中后、层次遍历

#include<iostream> #include<stack> #include<queue> using namespace std; /* 二叉树遍历算法递归+非递归: 前序遍历:根->左->右 中序遍历:左->根->右 后序遍历:左->右->根 层次遍历 */ struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x): val(x

二叉树的前序中序后序遍历相互求法

二叉树的前中后序遍历,他们的递归非递归.还有广度遍历,参见二叉树的前中后序遍历迭代&广度遍历和二叉树的前中后序遍历简单的递归 现在记录已知二叉树的前序中序后序遍历的两个,求另外一个.一般,这两个中一定有中序遍历. 1.已知前序和中序,求后序遍历: 前序:ABDECFG  中序:DBEAFCG 思路简单:前序的第一个节点就是根节点, 中序中找到根节点的位置,根节点之前是其左子树,之后是右子树   按此顺序,依次在左子树部分遍历,右子树部分遍历 C++ 代码: TreeNode *BinaryTre

经典白话算法之二叉树中序前序序列(或后序)求解树

这种题一般有二种形式,共同点是都已知中序序列.如果没有中序序列,是无法唯一确定一棵树的. <1>已知二叉树的前序序列和中序序列,求解树. 1.确定树的根节点.树根是当前树中所有元素在前序遍历中最先出现的元素. 2.求解树的子树.找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树.若根节点左边或右边为空,则该方向子树为空:若根节点 边和右边都为空,则根节点已经为叶子节点. 3.递归求解树.将左子树和右子树分别看成一棵二叉树,重复1.2.3步,直到所有的节点完成定

已知前序中序求后序-二叉树

writer:pprp 思路很容易理解,但是实现还是有一点难度,容易错 参考书目:<算法竞赛宝典> 代码如下: //已知前序中序,求后序 #include <iostream> using namespace std; //a是前序,b是中序 void hwg(string a,string b) { int ll,lr; for(unsigned int i = 0; i < b.length(); i++) { if(a[0] == b[i]) //找到根节点 { ll

算法进化历程之“根据二叉树的先序和中序序列输出后序序列”

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 前不久在看到一个作业"根据二叉树的先序和中序序列输出后序序列",当时我参考<数据结构与算法(C语言)习题集>上的做法,先根据先中序序列确定一颗二叉树,然后后序遍历二叉树输出后序序列. 函数采用了递归算法,利用函数传入的先序和中序序列的左右边界,确定要处理的序列段,生成相应的二叉树. 基本思路是,把该段先序序列的第一个元素作为当前二叉树的根结点,然后在中序序列找到根结点.根结点

分别求二叉树前、中、后序的第k个节点

一.求二叉树的前序遍历中的第k个节点 //求先序遍历中的第k个节点的值 int n=1; elemType preNode(BTNode *root,int k){ if(root==NULL) return ' '; if(n==k) return root->data; n++; elemType ch = preNode(root->lchild,k); if(ch!=' ') return ch; ch = preNode(root->rchild,k); return ch;

中序和后序遍历构造二叉树

题目链接: 涉及知识:二叉树的遍历 分析: 上一篇中介绍了如何通过二叉树的前序和中序遍历构造二叉树. 我们知道前序的遍历顺序是:根,左,右:中序的遍历顺序是左,根,右:后序的遍历顺序是左,右,根: 如果我们将后序遍历倒过来看便是根,右,左:会发现和前序遍历是非常相似的.前序遍历依次是根节点,左子树根节点,右子树根节点:后序遍历倒过来依次是根节点,右子树根节点,左子树根节点:因此解法和前序+中序生成后序的思路一样,从后序遍历中倒过来查找根节点,且先生成该节点的右子树,在生成该节点的左子树即可. 代

04已知先序中序或后序还原二叉树

首先,我们看看前序.中序.后序遍历的特性: 前序遍历: 1.访问根节点 2.前序遍历左子树 3.前序遍历右子树 (个人觉得这个命名略微有误导性,因为前序的“前”容易让人误会成树的最前边(视觉上的左边).记住前序遍历就是最直接(直觉上的)遍历——中左右) 中序遍历: 1.中序遍历左子树 2.访问根节点 3.中序遍历右子树 (同样是有误导性的名字. 遍历顺序——左中右) 后序遍历: 1.后序遍历左子树 2.后序遍历右子树 3.访问根节点 (同样是有误导性的名字,“后”字没有任何意义,所有二叉树的遍历