zoukankan      html  css  js  c++  java
  • 数据结构作业:利用中序遍历和后序遍历构建二叉树(RMQ转LCA)

      最近数据结构课给了一个二叉树的作业,给出二叉树的中序和后序遍历的序列,要求构建出改二叉树。我最初的时候是想到用map和RMQ来,以稳定O(nlogn)的时间构建这棵树。这样的复杂度已经是比普通的构建方法最坏情况O(n^2)(也就是单链的情况下)的复杂度要快不少的了。不过,今天在我打模板的时候找回我的笛卡尔树算法,那时忘记了是用来处理RMQ转LCA还是LCA转RMQ的了。于是,我就去回顾了一下LCA和RMQ的资料,发现RMQ是可以转成LCA的,其中区间最小值就是二叉树的对应的那两个端点结点的LCA(最低公共祖先)。以RMQ构建出来的树也恰好是我们想要的树。代码测试通过过小数据,准备用大数据来试下有没有什么漏洞 !

    用RMQ的代码,有点复杂。。。囧:

    View Code

    用笛卡尔树的代码,主要操作比较简短:

    View Code
      1 /*
      2 Author : SCAU_Lyon
      3 Class : Software Engineering Class 10
      4 Stu_ID : 201131001011
      5 Problem : build binary tree by in-order && post-order traverse
      6 Time Complexity : O(n)
      7 Algorithm : Cartesian Tree, Hash Table
      8 Date : 2012-11-05
      9 Declaration : At the second day, I find a new method to solve this problem with a more efficient and space-saving algorithm.
     10 Usage : First, input the size; then, input the in-order traverse list; last, input the post-order traverse list.
     11 Warning : Every key should be unique! And, the tree's size is better lower than 100000!
     12 */
     13 
     14 #include <cstdio>
     15 #include <cstring>
     16 #include <vector>
     17 #include <algorithm>
     18 
     19 using namespace std;
     20 
     21 typedef vector<int> vi;
     22 const int maxHash = 400009;
     23 const int HASH = 0x55555555;
     24 vi inOrder, postOrder;
     25 int hash[maxHash], hashPos[maxHash];
     26 
     27 void initHash() {
     28     memset(hashPos, -1, sizeof(hashPos));
     29 }
     30 
     31 void insHash(int pos, int key) {
     32     int p = ((key << 4) ^ HASH) % maxHash;
     33 
     34     if (p < 0) p += maxHash;
     35     while (hash[p] != key && ~hashPos[p]) {
     36         p++;
     37         if (p >= maxHash) p -= maxHash;
     38     }
     39 
     40     hash[p] = key;
     41     hashPos[p] = pos;
     42 }
     43 
     44 int getHash(int key) {
     45     int p = ((key << 4) ^ HASH) % maxHash;
     46 
     47     if (p < 0) p += maxHash;
     48     while (hash[p] != key && ~hashPos[p]) {
     49         p++;
     50         if (p >= maxHash) p -= maxHash;
     51     }
     52 
     53     return hashPos[p];
     54 }
     55 
     56 struct Node {
     57     int key, fix;
     58     Node *c[2], *p; // c[0] is the left child, c[1] is the right child
     59 
     60     Node(int _key = 0, int _fix = 0) {
     61         key = _key;
     62         fix = _fix;
     63         p = c[0] = c[1] = NULL;
     64     }
     65 } ;
     66 
     67 struct Cartesian {
     68     Node *Root, *Back;
     69 
     70     Cartesian() {
     71         Root = Back = NULL;
     72     }
     73 
     74     void delMain(Node *&rt) {
     75         if (!rt) return ;
     76         delMain(rt->c[0]);
     77         delMain(rt->c[1]);
     78         delete rt;
     79         rt = NULL;
     80     }
     81 
     82     void delTree() {
     83         delMain(Root);
     84     }
     85 
     86     void pushBack(Node *x) {
     87         while (Back && Back->fix < x->fix) {
     88             Back = Back->p;
     89         }
     90         if (Back) {
     91             x->c[0] = Back->c[1];
     92             if (Back->c[1]) {
     93                 Back->c[1]->p = x;
     94             }
     95             Back->c[1] = x;
     96             x->p = Back;
     97         } else {
     98             x->c[0] = Root;
     99             if (Root) Root->p = x;
    100             Root = x;
    101         }
    102         Back = x;
    103     }
    104 
    105     void _pushBack(int key, int fix) {
    106         Node *tmp = new Node(key, fix);
    107         pushBack(tmp);
    108     }
    109 
    110     void preTra(Node *rt) {
    111         if (!rt) return ;
    112         printf("%d ", rt->key);
    113         preTra(rt->c[0]);
    114         preTra(rt->c[1]);
    115     }
    116 
    117     void preTraverse() {
    118         puts("pre-traverse : ");
    119         preTra(Root);
    120         puts("");
    121     }
    122 
    123     void inTra(Node *rt) {
    124         if (!rt) return ;
    125         inTra(rt->c[0]);
    126         printf("%d ", rt->key);
    127         inTra(rt->c[1]);
    128     }
    129 
    130     void inTraverse() {
    131         puts("in-traverse : ");
    132         inTra(Root);
    133         puts("");
    134     }
    135 
    136     void postTra(Node *rt) {
    137         if (!rt) return ;
    138         postTra(rt->c[0]);
    139         postTra(rt->c[1]);
    140         printf("%d ", rt->key);
    141     }
    142 
    143     void postTraverse() {
    144         puts("post-traverse : ");
    145         postTra(Root);
    146         puts("");
    147     }
    148 } cart;
    149 
    150 void input(int n) {
    151     int x;
    152 
    153     inOrder.clear();
    154     postOrder.clear();
    155     initHash();
    156 
    157     for (int i = 0; i < n; i++) {
    158         scanf("%d", &x);
    159         inOrder.push_back(x);
    160     }
    161     for (int i = 0; i < n; i++) {
    162         scanf("%d", &x);
    163         postOrder.push_back(x);
    164         insHash(i, x);
    165     }
    166 }
    167 
    168 void buildTree(int n) {
    169     cart = Cartesian();
    170     for (int i = 0; i < n; i++) {
    171         cart._pushBack(inOrder[i], getHash(inOrder[i]));
    172     }
    173 }
    174 
    175 int main() {
    176     int n;
    177 
    178 //    freopen("in", "r", stdin);
    179     while (~scanf("%d", &n)) {
    180         input(n);
    181         buildTree(n);
    182         puts("Built Successfully!");
    183 
    184 //        cart.preTraverse();
    185 //        cart.inTraverse();
    186 //        cart.postTraverse();
    187 //        puts("");
    188         /*** You can add other functions here! ***/
    189 
    190         /*****************************************/
    191 
    192         cart.delTree();
    193     }
    194 
    195     return 0;
    196 }

      一个简单的算法就这样被我搞复杂了,还用了不少非教材上的算法。。。囧!不过还是挺好玩的~

     补充:通过大数据(100组约60000个结点的随机数据)的运算,算法1平均要27秒,算法2平均只要9秒~

    ——written by Lyon

  • 相关阅读:
    php mysql增删查改
    php文件上传代码解析
    php验证码
    html加javascript和canvas类似超级玛丽游戏
    javascript图片轮播
    php分页
    《Hadoop权威指南》笔记 第二章 Hadoop Streaming
    《Hadoop权威指南》笔记 第一章&第二章 MapReduce初探
    《深入理解Java虚拟机》笔记 第七章 虚拟机加载机制及双亲委派模型
    《深入理解Java虚拟机》笔记 第三章 内存分配与回收策略
  • 原文地址:https://www.cnblogs.com/LyonLys/p/DS_20121106_Lyon.html
Copyright © 2011-2022 走看看