Morris Traversal 二叉树遍历。
那天做了个SWAP NODE的题,要求constant space,不得不Morris Traversal。
稍微研究了一下,真正意义上的O(1)space对二叉树进行遍历。好像是1979年的算法。
第一次看着挺乱的,智商严重不足,不得不在纸上画出来,一目了然。。。建议大家自己动手画一下。
每个没有右节点的Node要建1个辅助path,回到他来自的那个左节点的parent。很绕口= =然后第二次来到这个点的时候,要去掉这个Path。所以每个点都遍历了2次,时间上还是O(n)..
和那个树状数组有点像,以每个左节点为中心。
import java.util.*;
public class Morris {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode (int v) {
this.val = v;
left = null;
right = null;
}
}
public static List<Integer> preOrder(TreeNode root) {
List<Integer> res = new ArrayList<>();
TreeNode temp = root;
while (temp != null) {
TreeNode morisTemp = temp;
if (temp.left != null) {
morisTemp = temp.left;
while (morisTemp.right != null && morisTemp.right != temp) {
morisTemp = morisTemp.right;
}
// first time, need to add a path
if (morisTemp.right == null) {
morisTemp.right = temp;
//res.add(temp.val); //pre-Order
temp = temp.left;
} else { // second time, remove the path we added,
morisTemp.right = null;
//res.add(temp.val); //in-Order
temp = temp.right;
}
} else {
res.add(temp.val);
temp = temp.right;
}
}
return res;
}
public static void main(String[] args) {
TreeNode n10 = new TreeNode(10);
TreeNode n4 = new TreeNode(4);
TreeNode n1 = new TreeNode(1);
TreeNode n5 = new TreeNode(5);
TreeNode n3 = new TreeNode(3);
TreeNode n6 = new TreeNode(6);
TreeNode n12 = new TreeNode(12);
TreeNode n11 = new TreeNode(11);
TreeNode n14 = new TreeNode(14);
TreeNode n15 = new TreeNode(15);
n10.left = n4;
n10.right = n12;
n4.left = n1;
n4.right = n5;
n5.left = n3;
n5.right = n6;
n12.left = n11;
n12.right = n14;
n14.left = n15;
for (int i : preOrder(n10)) {
System.out.print(i + " ");
}
}
}
preOrder和inOrder做出来了,postOrder有点麻烦,不会做= =再研究吧。。
Morris Traversal 二叉树遍历。的更多相关文章
- [转载]Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
本文主要解决一个问题,如何实现二叉树的前中后序遍历,有两个要求: 1. O(1)空间复杂度,即只能使用常数空间: 2. 二叉树的形状不能被破坏(中间过程允许改变其形状). 通常,实现二叉树的前序(pr ...
- Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)——无非是在传统遍历过程中修改叶子结点加入后继结点信息(传统是stack记录),然后再删除恢复
先看看线索二叉树 n个结点的二叉链表中含有n+1(2n-(n-1)=n+1)个空指针域.利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索 ...
- Morris Traversal 方法遍历二叉树(非递归、不用栈,O(1)空间)
http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html
- Morris Traversal方法遍历
实现二叉树的遍历且只需要O(1)的空间. 参考:http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html
- 二叉树中序遍历,先序遍历,后序遍历(递归栈,非递归栈,Morris Traversal)
例题 中序遍历94. Binary Tree Inorder Traversal 先序遍历144. Binary Tree Preorder Traversal 后序遍历145. Binary Tre ...
- C前序遍历二叉树Morris Traversal算法
首先来递归算法,简单易懂: #include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef ...
- 额外空间复杂度O(1) 的二叉树遍历 → Morris Traversal,你造吗?
开心一刻 一天,有个粉丝遇到感情方面的问题,找我出出主意 粉丝:我女朋友吧,就是先天有点病,听不到人说话,也说不了话,现在我家里人又给我介绍了一个,我该怎么办 我:这个问题很难去解释,我觉得一个人活着 ...
- [LeetCode] Binary Tree Inorder Traversal 二叉树的中序遍历
Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...
- 数据结构《10》----二叉树 Morris 中序遍历
无论是二叉树的中序遍历还是用 stack 模拟递归, 都需要 O(n)的空间复杂度. Morris 遍历是一种 常数空间 的遍历方法,其本质是 线索二叉树(Threaded Binary Tree), ...
随机推荐
- PL/SQL学习(一)
原文参考:http://plsql-tutorial.com/ 组成: 声明部分(可选) 执行部分(必选) 异常处理(可选) 声明: DECLARE 执行: ...
- C语言-04函数
1.参数 参数注意点 1.形式参数:定义函数时函数名后面中的参数,简称形参 2.实际参数:调用函数式传入的具体数据,简称实参 3.实参个数必须等于形参个数 4.函数体内部不能定义和形参一样的变量 5. ...
- Sql server中DateDiff用法【转】
记录下来.每次使用都忘记.... DATEDIFF 函数 [日期和时间] 功能 返回两个日期之间的间隔. 语法 DATEDIFF ( date-part, date-expression-1, dat ...
- C++默认参数值函数
1.默认参数值的函数 C++语言允许在定义函数时给其中或某些形式参数(形参)指定默认值,方法就是在相应的形参后面写上“=默认值”,如果省略了对应位置上的实参的值,则在执行被调函数时以该形参的默认值进行 ...
- Sprint5
进展:今天开始进行了登录界面的编写及实现. 燃尽图: 工作照:
- Matlab中Rand()函数用法
一.理论准备 matlab函数randn:产生均值为0,方差 σ^2 = 1,标准差σ = 1的正态分布的随机数或矩阵的函数. 用法:Y = randn(n),返回一个n*n的随机项的矩阵.如果n不是 ...
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
[题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...
- Eclipse下设置github开发环境
1.按照github上的指南配置(http://help.github.com/win-set-up-git/)基础的git环境. 2.在github上创建一个Repository. 3.在Eclip ...
- DHTMLX 前端框架 建立你的一个应用程序教程(一)
介绍 从这里下载官网 示例 此教程包含是多方面的: 1.如何在页面上添加标准的dhtmlx组建 2.如何在页面上组织组件 3.如何添加过滤 4.如何从服务器端获取数据填充组建 5.如何保存用户修改的数 ...
- SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-003-@Conditional根据条件生成bean及处理profile
一.用@Conditional根据条件决定是否要注入bean 1. package com.habuma.restfun; public class MagicBean { } 2. package ...