二叉树遍历

1.1、先序遍历 根结点-左子树-右子树

//---指针
void preorder(node* root)
{
    if(root==NULL) return; //空树,递归边界
    printf("%d
",root->data);
    preoder(root->lchild);
    preoder(root->rchild);
}
//---数组
void preorder(int root)
{
    if(root==-1) return;
    printf("%d
",Node[root].data);
    preorder(Node[root].lchild);
    preorder(Node[root].rchild);
}

1.2、中序遍历 左子树-根结点-右子树

//---指针
void inorder(node* root)
{
    if(root==NULL) return;
    inorder(root->lchild);
    printf("%d
",root->data);
    inorder(root->rchild);
}
//---数组
void inorder(int root)
{
    if(root==-1) return;
    inorder(Node[root].lchild);
    printf("%d
",Node[root].data);
    inorder(Node[root].rchild);
}

1.3、后序遍历 左子树-右子树-根结点

//---指针
void postorder(node* root)
{
    if(root==NULL) return;
    postorder(root->lchild);
    postorder(root->rchild);
    printf("%d
",root->data);
}
//---数组
void postorder(int root)
{
    if(root==-1) return;
    postorder(Node[root].lchild);
    postorder(Node[root].rchild);
    printf("%d
",Node[root].data);
}

1.4、层次遍历 

//层次遍历
//---指针
void Layerorder(node* root)
{
    queue<node*> que;
    root->layer=1;
    que.push(root);
    while(!que.empty())
    {
        node* one=que.front();
        que.pop();
        printf("%d ",one->data);
        if(one->lchild!=NULL)
        {
            one->lchild->layer=one->layer+1;
            que.push(one->lchild);
        }
        if(one->rchild!=NULL)
        {
            one->rchild->layer=one->layer+1;
            que.push(one->rchild);
        }
    }
}
//---数组
void Layerorder(int root){
    queue<int> que;
    que.push(root);
    while(!que.empty()){
        int now=que.front();
        que.pop();
        printf("%d ",Node[now].data);  //访问队首元素
        if(Node[now].lchild!=-1) que.push(Node[now].lchild);
        if(Node[now].rchild!=-1) que.push(Node[now].rchild);
    }
}

 

2.1 依据先序遍历和中序遍历构造二叉树

/*
先序遍历区间[preL,preR]
中序遍历区间[inL,inR]
numleft=k-inL
左子树
    先序区间:[preL+1,preL+numLeft]
    中序区间:[inL,K-1]
右子树
    先序区间:[preL+numLeft+1,preR]
    中序遍历区间:[k+1,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;
    for(k=inL,k<=inR;k++)
    {
        if(in[k]==pre[preL]) break;
    }
    int numLeft=k-inL;
    //返回左子树的根结点地址,赋值给root的左指针
    root->lchild=create(preL+1,preL+numLeft,inL,k-1);
    root->rchild=create(preL+numLeft+1,preR,k+1,inR);
    return root;
}

 

3、练习题

3.1 PTA A1020 Tree Traversals

https://pintia.cn/problem-sets/994805342720868352/problems/994805485033603072

依据后序遍历和中序遍历构造二叉树,并输出该二叉树的层次遍历序列

/*
后序遍历区间:[postL,postR]
中序遍历区间:[inL,inR]
numLeft=k-inL
左子树
    后序区间:[postL,postL+numLeft-1]
    中序区间:[inL,k-1]
右子树
    后序区间:[postL+numLeft,postR-1]
    中序区间:[k+1,inR]
*/
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
#define maxn 35
int pos[maxn];  //存放后序遍历结点的数据值
int in[maxn]; //存放中序遍历结点的数据值
int numLeft;
//二叉链表结构
typedef struct node{
    int data;
 //   int layer;
    node* lchild;
    node* rchild;
};
node* create(int postL,int postR,int inL,int inR);
void Layerorder(node* root);
int main()
{
    int n;
   // while(cin>>n){
        cin>>n;
        node* root=new node;
        pos[maxn]={0};
        in[maxn]={0};
        numLeft=0;
        for(int i=0;i<n;i++) cin>>pos[i];
        for(int i=0;i<n;i++) cin>>in[i];
        root=create(0,n-1,0,n-1);
        Layerorder(root);
  //  }
    return 0;
}
//create函数返回构建出的二叉树的根结点地址
node* create(int postL,int postR,int inL,int inR)
{
    if(postL>postR) return NULL; 
    node* root=new node;    //新建一个新结点
    root->data=pos[postR];
    int k;
    for(k=inL;k<=inR;k++)
    {
        if(in[k]==pos[postR]) break;
    }
    int numLeft=k-inL;
    //将左子树的根结点赋值给root的左指针
    root->lchild=create(postL,postL+numLeft-1,inL,k-1);
    //将右子树的根结点赋值给root的右指针
    root->rchild=create(postL+numLeft,postR-1,k+1,inR);
    return root;
}
void Layerorder(node* root)
{
    bool flag=true;
    queue<node*> que;
    que.push(root);
    while(!que.empty())
    {
        node* one=que.front();
        if(flag) {
            printf("%d",one->data);
            flag=false;
        }
        else printf(" %d",one->data);
        que.pop();
        if(one->lchild!=NULL) que.push(one->lchild);
        if(one->rchild!=NULL) que.push(one->rchild);
    }
    printf("
");
}
/*
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
4 1 6 3 5 7 2
8
4 8 5 2 7 6 3 1
4 2 8 5 1 6 7 3
1 2 3 4 5 6 8 7

*/

3.2、复原二叉树

http://codeup.cn/problem.php?cid=100000611&pid=0

给定二叉树的前序遍历和中序遍历,写出二叉树的后序遍历结果

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
#define maxn 100
typedef struct node{
    char data;
    struct node* lchild;
    struct node* rchild;
};
char pre[maxn],in[maxn];
node* create(int preL,int preR,int inL,int inR);
void postOrder(node* root);
void LayerOrder(node* root);
int main()
{
    string str1,str2;
    while(cin>>str1>>str2){
        node* root=new node;
        int len=str1.length();
        for(int i=0;i<len;i++) pre[i]=str1[i];
        for(int i=0;i<len;i++) in[i]=str2[i];
        root=create(0,len-1,0,len-1);
        postOrder(root);
        cout<<endl;
      //  LayerOrder(root);
    }
    return 0;
}
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;
    for(k=inL;k<=inR;k++){
        if(in[k]==pre[preL]) break;
    }
    int numLeft=k-inL;
    root->lchild=create(preL+1,preL+numLeft,inL,k-1);
    root->rchild=create(preL+numLeft+1,preR,k+1,inR);
    return root;
}
void postOrder(node* root)
{
    if(root==NULL){
        return;
    }
    postOrder(root->lchild);
    postOrder(root->rchild);
    cout<<root->data;
}
void LayerOrder(node* root)
{
    queue<node*> que;
    que.push(root);
    while(!que.empty()){
        node* one=que.front();
        cout<<one->data;
        que.pop();
        if(one->lchild!=NULL) que.push(one->lchild);
        if(one->rchild!=NULL) que.push(one->rchild);
    }
    cout<<endl;
}
/*
DBACEGF ABCDEFG
ACBFGED
BCAD CBAD
CDAB
*/

3.3、问题B:二叉树

http://codeup.cn/problem.php?cid=100000611&pid=1

①AC代码,数学处理 内存:2176KB 耗时:3ms

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    int m,n;
    int left,right;
    int cnt=0;
    while(cin>>m>>n)
    {
        if(m==0&&n==0) break;
        cnt=0;
        left=right=m;
        while(left<=n)
        {
            cnt+=(right-left+1);
            left=left*2;
            right=right*2+1;
            if(right>n) right=n;
        }
        cout<<cnt<<endl;
    }
    return 0;
}

② 递归,时间超限 内存:2176KB 耗时:1142ms

#include <cstdio>
#include <iostream>
using namespace std;
int m,n;
int ans=0;
void func(int m)
{
    if(m>n) return;
    func(2*m);
    func(2*m+1);
    ans++;
}
int main()
{
    while(scanf("%d%d",&m,&n))
    {
        if(m==0&&n==0) break;
        ans=0;
        func(m);
        printf("%d
",ans);
    }
    return 0;
}

③ 队列 ,内存超限 内存:32876KB 耗时:487ms

#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
int main()
{
 
    int m,n;
    while(cin>>m>>n)
    {
        int cou=0;
        if(m==0&&n==0) break;
        queue<int> que;
        que.push(m);
        while(!que.empty())
        {
            int value=que.front();
            if(value<=n) cou++;
            que.pop();
            if(2*value<=n) que.push(2*value);
            if(2*value+1<=n) que.push(2*value+1);
        }
        cout<<cou<<endl;
    }
    return 0;
}

3.4 、问题D:二叉树遍历

http://codeup.cn/problem.php?cid=100000611&pid=3

递归

#include <cstdio>
#include <iostream>
#include <stack>
using namespace std;
#define maxn 105
typedef struct node{
    char data;
    struct node* lchild;
    struct node* rchild;
};
int i=0;
char pre[maxn];
stack<node*> sta;
node* create();
void inOrder(node* root);
int main()
{
    string str;
    int len;
    while(gets(pre))
    {
        i=0;
        node* root=new node;
        root=create();
        inOrder(root);
        cout<<endl;
    }
    return 0;
}
node* create()
{
    node* root=new node;
    if(pre[i]=='#')
    {
        i++;
        return NULL;
    }
    root->data=pre[i];
    i++;
    root->lchild=create();
    root->rchild=create();
    return root;
}
void inOrder(node* root)
{
    if(root==NULL) return;
    inOrder(root->lchild);
    cout<<root->data<<" ";
    inOrder(root->rchild);
}
天晴了,起飞吧
原文地址:https://www.cnblogs.com/jianqiao123/p/14390892.html