zoukankan      html  css  js  c++  java
  • 通过层序和中序遍历序列重建二叉树

      在学二叉树的重建时,在《算法笔记》上学到了如何通过先序(或后序)遍历序列和中序遍历序列重建二叉树,它也提出了一个问题:如何通过层序和中序遍历序列重建二叉树?我一开始按照先序和中序重建的思路思考,发现做不到。我无法确定一个点后面的点属于它的左子树还是右子树或者兄弟节点。于是我在网上查找,发现这方面的话题不多,其中还有一些不是用C++实现的。不过幸好还是找到了。于是在学习之后在这把它记录下来。

     1 #include <cstdio>
     2 
     3 const int INF = 0x3fffffff;
     4 const int maxn = 10010;
     5 
     6 struct Node
     7 {
     8     int x;
     9     Node *left, *right;
    10 };
    11 
    12 Node* root;
    13 int levelorder[maxn], inorder[maxn];
    14 int n;
    15 bool hashtable[maxn];   //标记levelorder中某个点是否被加入了树中 
    16                         //如果没有hashtable, 当树中存在两个值相等的点时 , 
    17 Node* init()            //可能导致在层序遍历中相同值的两个点前面的点被遍历两次,后面的点 
    18 {                        //没有被遍历,从而建树错误 
    19     Node* node = new Node;
    20     node->x = 0;
    21     node->left = NULL;
    22     node->right = NULL;
    23     return node;
    24 }
    25 
    26 Node* buildtree(int il, int ir, int ll, int lr) //当我给你一个二叉树的中序遍历时 
    27 {                                                //这个中序遍历遍历一定有一个根节点  
    28     if(il == ir)                                //体现在层序遍历上时它一定先出现 
    29     {                                            //所以顺序遍历层序遍历,一定可以先发现二叉树的根节点  
    30         Node* node = new Node;
    31         node->x = inorder[il];
    32         hashtable[il] = true;
    33         return node;
    34     }
    35     Node* node = new Node;
    36     int i, j;
    37     for(j = ll; j <= lr; j++)
    38     {
    39         bool flag = false;
    40         for(i = il; i <= ir; i++)
    41         {
    42             if(inorder[i] == levelorder[j]&&hashtable[i] == false)
    43             {
    44                 flag = true;
    45                 break;
    46             }
    47         }
    48         if(flag) break;
    49     }
    50     node->left = buildtree(il, i-1, j+1, lr);
    51     node->right = buildtree(i+1, ir, j+1, lr);
    52     node->x = inorder[i];
    53     hashtable[i] = true;
    54     return node;
    55 }
    56 
    57 int main()
    58 {
    59     scanf("%d", &n);
    60     for(int i = 0; i < n; i++) scanf("%d", &inorder[i]);
    61     for(int i = 0; i < n; i++) scanf("%d", &levelorder[i]);
    62     root = buildtree(0, n-1, 0, n-1);
    63     printf("%d\n", root->left->right->x);
    64     return 0;
    65 }

      这个重建的方法利用了层序遍历序列中父子节点有先后顺序的特点。

  • 相关阅读:
    内置函数详解
    关于内置函数
    ac自动机练习 HihoCoder 1036
    字典树Trie练习 HihoCoder 1014
    HDU 6170 Two String 动态规划
    NOJ 1190 约瑟夫问题 线段树OR树状数组
    NOJ 1186 灭蚊药水
    LightOJ 1085 树状数组+动态规划
    LightOJ 1066
    LightOJ 1080 树状数组
  • 原文地址:https://www.cnblogs.com/thesky/p/10614313.html
Copyright © 2011-2022 走看看