zoukankan      html  css  js  c++  java
  • 二叉树遍历

    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);
    }
    天晴了,起飞吧
  • 相关阅读:
    MySQL主库异常,从库手动切换为主库方案
    快速搭建应用服务日志收集系统(Filebeat + ElasticSearch + kibana)
    CentOS7设置DNS服务器
    nginx/iptables动态IP黑白名单实现方案
    Python批量复制和重命名文件
    centos 7 配置php运行环境 (新)
    配置Nginx和php-fpm用Sock套接字连接时,找不到php-fpm.sock的原因
    php-fpm nginx 9000端口
    nginx与php-fpm通信的两种方式
    centos 7.2 常用命令useradd的使用
  • 原文地址:https://www.cnblogs.com/jianqiao123/p/14390892.html
Copyright © 2011-2022 走看看