测评链接:LeetCode 94. Binary Tree Inorder Traversal
Morris遍历实现后序遍历Morris遍历实现后序遍历相对比较麻烦 , 处理时机只放在能回到自己两次的点,能回到自己两次的点在第二次回到自己的时刻,不打印它自己 , 而是逆序打印他左树的右边界, 整个遍历结束后,单独逆序打印整棵树的右边界,即得到了后序遍历的结果 。
代码如下:
public List<Integer> postorderTraversal(TreeNode root) {if (root == null) {return new ArrayList<>();}List<Integer> ans = new ArrayList<>();TreeNode cur = root;TreeNode mostRight;while (cur != null) {mostRight = cur.left;if (mostRight != null) {while (mostRight.right != null && mostRight.right != cur) {mostRight = mostRight.right;}if (mostRight.right == null) {mostRight.right = cur;cur = cur.left;continue;} else {mostRight.right = null;// 第二次来到自己的时候,收集自己的左树的右边界collect(cur.left, ans);}}cur = cur.right;}collect(root, ans);return ans;}private void collect(TreeNode root, List<Integer> ans) {TreeNode node = reverse(root);TreeNode c = node;while (c != null) {ans.add(c.val);c = c.right;}reverse(node);}private TreeNode reverse(TreeNode node) {TreeNode pre = null;TreeNode cur = node;while (cur != null) {TreeNode t = cur.right;cur.right = pre;pre = cur;cur = t;}return pre;}
需要注意两点:
第一点,collect
方法即逆序收集左树的有边界,由于每个节点没有指向父的指针 , 所以,要实现逆序,需要针对右边界采用反转链表的方式 。即reverse
函数的逻辑 。
第二点,在collect
方法调用完反转链表操作后,还要还原整个右边界 。否则整棵树的指针就指乱了 。
测评链接:LeetCode 145. Binary Tree Postorder Traversal
更多算法和数据结构笔记
参考资料算法和数据结构体系班-左程云
推荐阅读
- vue实现功能 单选 取消单选 全选 取消全选
- VLQ & Base64 VLQ 编码方式的原理及代码实现
- Object Detection 【YOLOv5】LabVIEW+YOLOv5快速实现实时物体识别含源码
- 驱动开发:内核遍历进程VAD结构体
- Springboot 之 Filter 实现超大响应 JSON 数据压缩
- SpringBoot 自定义注解 实现多数据源
- .NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实现
- 驱动开发:内核中实现Dump进程转储
- OnionArch - 如何实现更新指定字段的通用Handler
- 如何用AR Engine环境Mesh能力实现虚实遮挡