zoukankan      html  css  js  c++  java
  • 二叉树重建

    一棵二叉树:

    树的先序遍历序列preorder:DBACEGF(根左右)

    树的中序遍历序列inorder:ABCDEFG(左根右)

    树的后序遍历序列postorder:ACBFGED(左右根)

    树的层序遍历序列levelorder:DBEACGF(按行遍历)

    输入一棵二叉树的先序遍历和中序遍历序列,输出它的后序遍历序列。

      输入:DBACEGF ABCDEFG  输出:ACBFGED 

    思路:

    已知先序遍历序列的第一个一定是本树的根节点,而后在中序遍历中找到该根节点的位置,中序遍历序列中根节点左边为左子树,右边为右子树,然后开始先左子树后右子树进行递归,因为要求的后序遍历序列是左右根,故在递归完左右子树后再输出根。

     Code:

     1 #include<bits/stdc++.h>
     2 #define IO ios::sync_with_stdio(false)
     3 using namespace std;
     4 string preorder,inorder,aa;//分别为先序、中序、后序
     5 int n,t;
     6 void recover(int l,int r)
     7 {
     8     if(l>=r)return;
     9     int root=preorder[t++];//先序遍历的第一个点一定是根节点
    10     int m=distance(inorder.begin(),find(inorder.begin(),inorder.end(),root));//找到中序中的根节点位置
    11     recover(l,m);//根节点的左子树
    12     recover(m+1,r);//右子树
    13     aa.push_back(root);//因为要求后序遍历,所以根最后输出
    14 }
    15 int main()
    16 {
    17     IO;
    18     while(!(cin>>preorder>>inorder).eof())
    19     {
    20         aa.clear();
    21         t=0;
    22         recover(0,preorder.size());
    23         for(int i=0;i<aa.size();i++){
    24             cout<<aa[i];
    25         }
    26         cout<<endl;
    27     }
    28     return 0;
    29 }
    View Code

    输入一棵二叉树的中序遍历和后序遍历序列,输出它的先序遍历序列。   
     输入:
    ABCDEFG ACBFGED 输出:DBACEGF

    思路:
    已知后序遍历的最后一个一定是本树的根节点,所以先从后序中找到当前树的根并输出(因为所要求的先序遍历是根左右,故找到根后就输出),然后去中序里

    找该根的位置,将中序划为两棵子树(中序遍历中根节点左边为其左子树,右边为其右子树),之后开始进行递归。

    Code:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 string preorder,inorder,postorder;
     4 void recover(int l,int r)
     5 {
     6     string t(inorder,l,r-l+1);//将中序序列inorder的l位置起r-l+1位复制给数组t
     7     int vis=postorder.find_last_of(t);//后序遍历所找到的最后一个一定当前序列t的根
     8     preorder.push_back(postorder[vis]);//要求先序,故先输出根,下面再分左右子树去递归
     9     int m=inorder.find(postorder[vis]);//根在中序遍历中的位置m,中序遍历中根左边为左子树,根右边为右子树
    10     if(m!=l)
    11         recover(l,m-1);//左子树递归
    12     if(m!=r)
    13         recover(m+1,r);//右子树递归
    14 }
    15 int main()
    16 {
    17     while(!(cin>>inorder>>postorder).eof())//输入中序遍历和后序遍历的序列
    18     {
    19         preorder.clear();//多测试用例故要清空
    20         recover(0,inorder.size()-1);
    21         cout<<preorder<<endl;//输出先序遍历序列
    22     }
    23     return 0;
    24 }
    View Code
    
    
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 void recover(string zhong,string hou){
     4     if(zhong.size()>0){
     5         char root=hou[hou.size()-1];//后序的最后一个为根节点
     6         cout<<root;//输出根
     7         int vis=zhong.find(root);//该根在中序中的位置
     8         recover(zhong.substr(0,vis),hou.substr(0,vis));//递归左子树
     9         recover(zhong.substr(vis+1),hou.substr(vis,zhong.size()-vis-1));//递归右子树
    10     }
    11 }
    12 int main()
    13 {
    14     string inorder,postorder;
    15     while(cin>>inorder>>postorder)
    16     {
    17         recover(inorder,postorder);
    18         cout<<endl;
    19     }
    20     return 0;
    21 }
    View Code
    知道中序和后序遍历,画二叉树和写出前序遍历

    输入一颗二叉树的先序遍历和中序遍历序列,输出它的层序遍历序列。  
      输入:DBACEGF ABCDEFG 输出:DBEACGF
    层序遍历思路:
    创建一个队列,先将根节点入队,输出根节点,将根节点的儿子先左后右入队,根节点出队,如此循环直到队列为空。

    Code:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 struct TreeNode
     4 {
     5     TreeNode *l,*r;
     6     char data;
     7 };
     8 TreeNode *create(char *pre,char *mid,int len) //三个参数分别为先序序列,中序序列,序列长度
     9 {
    10     if(len<=0)
    11         return NULL; //空节点
    12     TreeNode *root;
    13     root=new TreeNode;
    14     root->data=pre[0]; //先序遍历的第一个一定是根节点,如此迭代
    15     int i;
    16     for(i=0;i<len;i++){
    17         if(mid[i]==pre[0]) //在中序遍历中找到该根节点的位置
    18             break;
    19     }
    20     root->l=create(pre+1,mid,i); //递归左子树,左子树中先序遍历字串向后挪一位,中序不变,但i控制了长度
    21     root->r=create(pre+i+1,mid+i+1,len-i-1);//递归右子树,右子树中先序遍历和中序遍历都向后挪i+1位,长度变成总长度减去前半部分的长度
    22     return root;
    23 }
    24 void levelorder(TreeNode *root) //层序遍历
    25 {
    26     queue<TreeNode*>que;//注意是TreeNode*
    27     if(root){ //一定要特判,不然会RE
    28         que.push(root);
    29         cout<<que.front()->data;
    30     }
    31     while(que.size())
    32     {
    33         TreeNode *root=que.front();
    34         que.pop();
    35         if(root->l){ //依次找左右儿子输出
    36             cout<<root->l->data;
    37             que.push(root->l);
    38         }
    39         if(root->r){
    40             cout<<root->r->data;
    41             que.push(root->r);
    42         }
    43     }
    44 }
    45 void postorder(TreeNode *root) //后序遍历
    46 {
    47     if(!root)
    48         return;
    49     postorder(root->l);
    50     postorder(root->r);
    51     cout<<root->data;
    52 }
    53 
    54 int main()
    55 {
    56     char preorder[1000],inorder[1000];
    57     while(!(cin>>preorder>>inorder).eof())//输入先序遍历序列和中序遍历序列
    58     {
    59         TreeNode *root;
    60         int len=strlen(preorder);
    61         root=create(preorder,inorder,len);
    62         levelorder(root);cout<<endl; //输出层序遍历序列
    63         postorder(root);cout<<endl; //输出后序遍历序列
    64     }
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    ASP.NET MVC2 in Action 读书笔记 [121] Custom Ajax
    [转] 浅谈 MVC3 WebMail 发送邮件
    JQuery学习笔记 (3)
    ASP.NET MVC2 in Action 读书笔记 [1]
    [转] 在ASP.NET MVC3中使用EFCodeFirst 1.0
    LINQ ForEach
    JQuery学习笔记 [Ajax实现新闻点评功能] (63)
    [转] .NET2005下单元测试中Assert类的用法
    [转] ASP.NET MVC3 路由和多数据集的返回
    ASP.NET MVC2 in Action 读书笔记 [124] MVC Ajax Helpers
  • 原文地址:https://www.cnblogs.com/HOLLAY/p/11299198.html
Copyright © 2011-2022 走看看