《编程之美》读书笔记19: 3.9 重建二叉树

对根节点a以及先序遍历次序P和中序遍历次序I,查找a在I中的位置,将I分为两部分,左边部分的元素都在a的左子树上,右边的元素都在a的右子树上,因而可以确定a的左子树节点数和a的右子树节点数,再结合P,可以确定a的左孩子和右孩子,以及各个孩子的先序和中序遍历次序。

由于已经知道节点数,可以事先分配好内存,可以按先序遍历次序连续存放节点。

rebuild_tree_1struct Node {
  Node* left;
  Node* right;
  char data;
};

void rebuild(char preorder[], char inorder[], Node result[], size_t size)
{
  result->data = *preorder;
  result->left=NULL;
  result->right=NULL;
  char *p = inorder;
  size_t left_size=0;
  while (left_size<size && *p++!=*preorder) ++left_size;
  assert (left_size<size);
  size_t right_size = size-1-left_size;
  if (left_size) {
    result->left=result+1;
    rebuild(preorder+1, inorder, result+1, left_size);
  }
  if (right_size) {
    result->right=result+left_size+1;
    rebuild(preorder+left_size+1, inorder+left_size+1,
            result+left_size+1, right_size);
  }
}

上面的代码,栈深度是O(n),有可能出现栈溢出,可以修改代码,减少一次递归调用,实现栈深度为O(lg n)。

rebuild_tree_2void rebuild2(char preorder[], char inorder[], Node result[], size_t size)
{
  while (1){
    result->data = *preorder;
    result->left=NULL;
    result->right=NULL;
    char *p = inorder;
    size_t left_size=0;
    while (left_size<size && *p++!=*preorder) ++left_size;
    assert (left_size<size);
    size_t right_size = size-1-left_size;
    if (left_size==0 && right_size==0) break;
    if (left_size<right_size) {
      if (left_size) {
        result->left=result+1;
        rebuild2(preorder+1, inorder, result+1, left_size);
      }
      result->right=result+left_size+1;
      preorder += left_size+1;
      inorder += left_size+1;
      result += left_size+1;
      size = right_size;
    } else {
      if (right_size) {
        result->right=result+left_size+1;
        rebuild2(preorder+left_size+1, inorder+left_size+1,
                 result+left_size+1, right_size);
      }
      if (left_size) {
        result->left=result+1;
        ++preorder;
        ++result;
        size = left_size;
      }
    }
  }
}

书上的代码(P246):

* pTemp = new NODE;
  pTemp -> chValue = *pPreOrder;
  pTemp -> pLeft = NULL;
  pTemp -> pRight = NULL;
  
  // 如果节点为空,把当前节点复制到根节点
  if(*pRoot == NULL)
  {
       *pRoot = pTemp;
  }

可能引起内存泄漏(当*pRoot!=NULL,新申请的内存没释放),注释也不对(不是复制节点,而是更改指针指向新建的节点)。另外,频繁的new,极有可能会产生内存碎片。当节点很小时,内存浪费很严重(每new一次都要额外分配空间储存相关信息)。

转载于:https://www.cnblogs.com/flyinghearts/archive/2011/03/22/1991992.html

《编程之美》读书笔记19: 3.9 重建二叉树相关推荐

  1. 编程之美 - 读书笔记 - 卖书折扣问题的贪心解法

    <编程之美>读书笔记(四):卖书折扣问题的贪心解法 每 次看完<编程之美>中的问题,想要亲自演算一下或深入思考的时候,都觉得时间过得很快,动辄一两个小时,如果再把代码敲一遍的话 ...

  2. 编程之美读书笔记之-高效率的安排见面会

    问题一: n个同学,分别对m个招聘见面会感兴趣.为了满足所有学生的要求,hr希望让每个同学都能参加自己所有感兴趣的见面会.然后每个见面会的时间为t.问如何安排见面会能够使得所有见面会总的时间最短. 建 ...

  3. 【编程之美/读书笔记】Chapter 1 游戏之乐

    这里就不写每个问题的题目了,只是记录一下自己的总结和心得. 1.1 让CPU占用率听你指挥 这个题目我刚接触的想法是和多核多线程要扯上关系的,因为自己写个死循环只能跑到CPU 35%左右的占用率,但是 ...

  4. Java并发编程之美读书笔记-并发编程基础2

    2019独角兽企业重金招聘Python工程师标准>>> 1.线程的通知与等待 Java中的Object类是所有类的父亲,鉴于继承机制,Java把所有类都需要的方法放到了Object类 ...

  5. 编程之美读书笔记2.1—求二进制数中1的个数

    解法一: 可以举一个8位二进制的例子.对于二进制操纵,我们除以一个2,原来数字就会减少一个0(向右移一位).如果除的过程中有余,那么久表示当前位置有一个1. 以10100010为例: 第一次除以2时, ...

  6. 编程之美--读书笔记--返回一个数组中所有元素被第一个元素除的结果

    笔试题目1:写一个函数,返回一个数组中所有元素被第一个元素除的结果 很多人会想到如下: void DivAarry(int *pArray,int size) { for(int i=size-1;i ...

  7. 中国象棋将帅问题java_编程之美读书笔记1.2——中国象棋将帅问题

    http://blog.csdn.net/pipisorry/article/details/36380669 问题:下过中国象棋的朋友都知道,双方的"将"和"帅&quo ...

  8. 编程之美 - 读书笔记 - 烙饼问题与搜索树

    前 面已经写了一些关于烙饼问题的简单分析,但因为那天太累有些意犹未尽,今天再充实一些内容那这个问题研究透.我想,通过这篇文章,我们就可以把这一类问题 搞懂.再遇到优化问题,如果我们想不到别的办法,就可 ...

  9. 编程之美读书笔记_1.1_让CPU占用率曲线听你指挥

    题目:写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率.程序越精简越好,计算机语言不限.例如,可以实现下面三种情况:   1.    CPU的占用率固定在50 ...

最新文章

  1. redis-sentinel 主从复制高可用
  2. 修改IIS7并发连接数目限制
  3. php创建输入文本框,Asp:文本框与输入文本(PHP开发人员学习ASP)
  4. php面试宝典1000题,【PHP面试宝典1000题】HTTP中的请求头(深圳小美网络科技)
  5. ORA-39171: 作业出现可恢复的等待
  6. Skywalking-11:Skywalking查询协议——案例分析
  7. 如何安装最新版本Pycharm2019
  8. Datatables + Bootstrap
  9. Less 混合(mixin)
  10. 生成Oracle的AWR报告
  11. 让Spring 3中jsp的数据对象使用懒加载(FetchType.LAZY)与Controller的JSR 303并存
  12. 优美的js代码,拿去玩~
  13. 整理 linux常用命令及工具
  14. VMware 虚拟机运行卡慢的解决办法
  15. Java实现首字母转大写、小写StringUtils.capitalize
  16. f1c100s 源码_F1C100S 简易 boot 原理
  17. 华为2019年3月27日实习生笔试题及解答
  18. 【codejam_Round1B_C】Mousetrap
  19. 勃林格殷格翰2022年营收强势增长10.5%,达241亿欧元
  20. ResNet详解:ResNet到底在解决什么问题?

热门文章

  1. C++_STL标准库——容器
  2. 如何在简历中添加自己的CSDN博客链接
  3. mysql整形溢出报错_MySQL整型数据溢出的解决方法
  4. 这一篇让你真正理解Mysql的四种隔离级别
  5. php程序耗时是负数,php 代码测试,代码越在前面越耗时
  6. python加密库_python基于pyDes库实现des加密的方法
  7. mysql 5.6 rpm 安装_mysql 5.6 rpm 包安装步骤需要注意的地方
  8. mysql中文乱码解决方案_关于MySQL中文乱码的完美解决方案
  9. 计算机应用基础课程是过程化考试吗,基于能力的计算机应用基础课程过程化考核标准构建与实施...
  10. php多维数组和对象,在PHP中将多维多对象数组转换为标准多维数组