二叉树理解与实践

还原二叉树
二叉树常用遍历有4种:中序(inorder)、前序/先序(preorder)、后序(postorder)、层序(levelorder),通常该类型题目会让你从前三者中选两种还原成一棵树。(当然,
树的各个节点number不同

后序+中序:
Pat 1020. Tree Traversals

该题关键是考虑一棵树遍历下后序与中序的关系:后序的末尾一定是根,假设是tail,那么在中序序列找到tail的位置,以此分开的左右序列刚好是tail的左右子树,那么根据
中序序列的 左子树长度与
后序序列里的左子树在左边 就可以确定左子树范围,很容易得到剩下的右子树,往子树递归即可

··············································································

前序+中序:
1086. Tree Traversals Again (25)

与上题类似,对前序的要跟后序反过来看:前序第一个节点肯定是根节点,同样根据在中序找到的左右子树长度在前序确定位置即可。不过前序的左子树接着根,右子树在右边~

值得注意的是我们完全可以不必重建树,而是填入一个size一样的vector里面即可

···············································································

前序+后序:
1119. Pre- and Post-order Traversals (30)

看上面两道的时候如果已经有对中序把3者连接起来的准备,那么根肯定能找到:分别在前序首位和后序尾部,问题是左子树和右子树之间的分离!

上过数据结构的课应该都会知道,光有前序和后序是未必能还原出一棵树的!但是我们得搞清楚到底是缺少了哪些信息:一棵树(或者子树)只有一个孩子的时候,通过前序和后序是不清楚这是左还是右的!

而前序里面,
左子树根在第二个位置,右子树根看左子树长度;后序里面,
右子树根在倒数第二个位置;那么当一棵树某个节点只有一个孩子时,你会发现这个孩子就靠在树根旁边,从前序看是左子树,后序看是右子树!

也就是说:一般情形下,树有左右儿子时,

preorder[1] != postorder[倒数第二]

那么我们就可以把他们其中一棵看成中序效仿前题得到左右子树长度,分离子树,往子树递归

当单个孩子出现,
preorder[1] == postorder[倒数第二],这个孩子我们可以当它是左孩子或者右孩子都行!反正这时是单递归的!

特殊二叉树构建
诸如二叉搜索树(bst)、完全二叉树(CBT)、平衡二叉树也会在考试中出现。除了像AVL这种特别BT的实现考察,一般如果找到特别的规律,答案会显得非常简洁

完全二叉搜索树树
1110. Complete Binary Tree (25)

一道题考察了两个点:1.二叉搜索树的特质是左小右大,这会导致其中序遍历是有序的!(上过MIT算法导论的应该知道,这实际是对数据进行快排的过程);2.完全二叉树用数组实现是稠密的,也就是从1开始到树的大小这么多的数组空间刚好容纳一棵树,且左子树是2N,右子树是2N+1

所以这道题我们直接申请树的节点+1那么多的数组空间,从vec[1]开始看成一棵树,不超过size前提下中序遍历,把排序的节点填进去即可构建完成

·········································································

平衡二叉树
1066. Root of AVL Tree

除了旋转还是旋转,害怕.jpg,希望考试别碰到。。。

·········································································

建立BST
1099. Build A Binary Search Tree (30)

其实这道题不仅是建立树那么简单,还是个找规律的题!

实际上里面这棵树是用数组建立的,如果你光看样例,以为规律是:按树的先序列出其左右儿子,那就GG了—-只有20+分吧。其实还有个规律就是那些节点原本数字刚好是它们用数组实现的节点下标啊啊啊啊

同样可以通过找规律实现的还有1086、1020最上面那两道题,不必建立树,某种堆栈访问模拟即可。

点赞