Java morris遍历的用例
我已经写了一个程序,它使用morris遍历来遍历二叉树。出于好奇,我开始在inorder traversal和morris traversal之间进行基准测试。 我发现在运行1000次之后,morris遍历的平均时间是5795次,递归顺序遍历的平均时间是2457次,几乎是morris遍历的两倍 我认为使用线程二叉树的morris遍历具有复杂性O(NlogN),递归有序遍历具有O(N),因此显然morris遍历将花费更多的时间。 我的问题如下:Java morris遍历的用例,java,algorithm,data-structures,Java,Algorithm,Data Structures,我已经写了一个程序,它使用morris遍历来遍历二叉树。出于好奇,我开始在inorder traversal和morris traversal之间进行基准测试。 我发现在运行1000次之后,morris遍历的平均时间是5795次,递归顺序遍历的平均时间是2457次,几乎是morris遍历的两倍 我认为使用线程二叉树的morris遍历具有复杂性O(NlogN),递归有序遍历具有O(N),因此显然morris遍历将花费更多的时间。 我的问题如下: 我提到的时间复杂性是正确的吗 如果morris遍历
- 我提到的时间复杂性是正确的吗
- 如果morris遍历在这里非常慢,那么在递归并不昂贵的java世界中,它的用例是什么呢李>
- 我关于递归在
w.r.t.语言(如java
)中成本不高的断言是否正确? 提前谢谢C
public class ThreadedBinaryTree<T extends Comparable<T>>
{
private TreeNode root;
public void morrisTraverse()
{
TreeNode current = root;
if(current == null)
{
return;
}
while(current != null)
{
if(current.left != null)
{
TreeNode temp = current.left;
while(true)
{
if(temp.right == null) break;
if(temp.right == current) break;
temp = temp.right;
}
if(temp.right == null)
{
//create the link to predecessor
temp.right = current;
current = current.left;
}
else
{
//remove the link
temp.right = null;
//System.out.println(current.t);
current = current.right;
}
}
else
{
//System.out.println(current.t);
current = current.right;
}
}
}
public void inorder()
{
inorder(root);
}
private void inorder(TreeNode node)
{
if(node != null)
{
inorder(node.left);
//System.out.println(node.t);
inorder(node.right);
}
}
private static class TreeNode<T extends Comparable<T>>
{
private T t;
private TreeNode left;
private TreeNode right;
private TreeNode(T t)
{
this.t = t;
}
}
}
public static void main(String[] args)
{
ThreadedBinaryTree binaryTree = new ThreadedBinaryTree();
binaryTree.insert(500);
binaryTree.insert(20);
binaryTree.insert(15);
binaryTree.insert(25);
binaryTree.insert(40);
binaryTree.insert(35);
………….
…………..
…………. some more inserts to tree
int index = 1;
long moris = 0;
long normal = 0;
while(index <= 1000)
{
long start = System.nanoTime();
binaryTree.morrisTraverse();
moris += System.nanoTime() -start;
//System.out.println("__________________________________________________________");
long start1 = System.nanoTime();
binaryTree.inorder();
normal+=System.nanoTime() -start1;
index++;
}
System.out.println(moris/1000);
System.out.println(normal/1000);
}
公共类ThreadedBinaryTree
{
独活根;
公众假期(星期日)
{
TreeNode电流=根;
如果(当前==null)
{
返回;
}
while(当前!=null)
{
if(current.left!=null)
{
TreeNode温度=当前。左侧;
while(true)
{
如果(temp.right==null)中断;
如果(右侧温度==当前)断路;
温度=右侧温度;
}
if(temp.right==null)
{
//创建指向Preference的链接
右侧温度=电流;
current=current.left;
}
其他的
{
//移除链接
temp.right=null;
//系统输出打印项次(当前t);
current=current.right;
}
}
其他的
{
//系统输出打印项次(当前t);
current=current.right;
}
}
}
公共无效序()
{
顺序(根);
}
私有void索引(树节点)
{
如果(节点!=null)
{
顺序(node.left);
//System.out.println(node.t);
顺序(node.right);
}
}
私有静态类树节点
{
私人T;
私有树节点左;
私有树节点权;
私有树节点(T)
{
t=t;
}
}
}
驱动程序程序:
public class ThreadedBinaryTree<T extends Comparable<T>>
{
private TreeNode root;
public void morrisTraverse()
{
TreeNode current = root;
if(current == null)
{
return;
}
while(current != null)
{
if(current.left != null)
{
TreeNode temp = current.left;
while(true)
{
if(temp.right == null) break;
if(temp.right == current) break;
temp = temp.right;
}
if(temp.right == null)
{
//create the link to predecessor
temp.right = current;
current = current.left;
}
else
{
//remove the link
temp.right = null;
//System.out.println(current.t);
current = current.right;
}
}
else
{
//System.out.println(current.t);
current = current.right;
}
}
}
public void inorder()
{
inorder(root);
}
private void inorder(TreeNode node)
{
if(node != null)
{
inorder(node.left);
//System.out.println(node.t);
inorder(node.right);
}
}
private static class TreeNode<T extends Comparable<T>>
{
private T t;
private TreeNode left;
private TreeNode right;
private TreeNode(T t)
{
this.t = t;
}
}
}
public static void main(String[] args)
{
ThreadedBinaryTree binaryTree = new ThreadedBinaryTree();
binaryTree.insert(500);
binaryTree.insert(20);
binaryTree.insert(15);
binaryTree.insert(25);
binaryTree.insert(40);
binaryTree.insert(35);
………….
…………..
…………. some more inserts to tree
int index = 1;
long moris = 0;
long normal = 0;
while(index <= 1000)
{
long start = System.nanoTime();
binaryTree.morrisTraverse();
moris += System.nanoTime() -start;
//System.out.println("__________________________________________________________");
long start1 = System.nanoTime();
binaryTree.inorder();
normal+=System.nanoTime() -start1;
index++;
}
System.out.println(moris/1000);
System.out.println(normal/1000);
}
publicstaticvoidmain(字符串[]args)
{
ThreadedBinaryTree binaryTree=新的ThreadedBinaryTree();
插入(500);
插入(20);
插入(15);
插入(25);
插入(40);
插入(35);
………….
…………..
更多插入到树中
int指数=1;
long-moris=0;
长正态=0;
while(索引)
我提到的时间复杂性是正确的吗
不,莫里斯遍历也是线性的
如果morris遍历在这里非常慢,那么在递归成本不高的java世界中,它的用例是什么
Morris不使用额外的空间。递归使用堆栈空间。如果这是有足够内存和没有足够内存的区别,那么您可能不应该首先选择Java
我关于递归在java w.r.t.语言(如C)中成本不高的断言是否正确
这是一个计算属性,而不是语言规范。没有任何特定的实现困难会先验地指出一个比另一个更有效。不,Morris遍历也是线性的。
。当算法为每个节点查找顺序前导时,查找前导需要logN和遍历是N。所以时间复杂度是O(NlogN)。如果我错了,请纠正我。谢谢。@尝试O(logn)最坏的情况,在平衡树中(这不是),但摊销成本是O(1)感谢您的努力。仍然和摊余成本混淆。您能告诉我一件事吗,假设树是平衡二叉树,我正在进行顺序和莫里斯遍历。我能说最坏情况下的时间复杂度是O(N)和O(NlogN)吗?如果可能,请引导我找到摊余成本的一些链接。@try每个树边向下和向上遍历一次。每个节点遍历的平均边数是O(1),因为有n-1个边和n个节点。你是正确的,但我想你还没有看到我的代码public void morristroverse()
它正在创建线程化二叉树,并在其上遍历,然后重新初始化为初始树。由于我在一个阶段中结合了创建和遍历,因此线程化二叉树的创建需要O(NLogN)和遍历需要O(N).因此我感到困惑,如果我将两者分开,那么我会正确计算复杂性。请遵守。谢谢。