Я написал программу, которая использует обход морриса для прохождения двоичного дерева. И для любопытства я начал выполнять бенчмаркинг между обходным путем и прохождением морриса. Я обнаружил, что после запуска в 1000 раз среднее время прохождения морриса составляет 5795, а для рекурсивного обхода порядка 2457, что почти в два раза быстрее, чем обход морриса.Пример использования morris traversal
Я думаю, что обход morris, который использует резьбовое двоичное дерево, имеет сложность O (NlogN), а рекурсивный обход по порядку имеет O (N), поэтому очевидно, что обход morris займет больше времени. Вопрос:
- - это временная сложность, о которой я упоминал правильно?
- Если обход morris здесь довольно медленный, тогда какой прецедент этого в java-мире, где рекурсия не очень дорогостоящая.
- Мое утверждение, что рекурсия не является дорогостоящей в
java
w.r.t. Языки, подобные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);
}
'Нет, обход Морриса также линейный .'. Поскольку алгоритм находит предшественника порядка для каждого узла, тогда поиск предшественника принимает logN, а обход - N. Таким образом, сложность времени приходит к O (NlogN). Пожалуйста, поправьте меня, если я ошибаюсь. Благодарю. – Trying
@ Пробуждение O (log n) * наихудший случай *, в сбалансированном дереве (которого это не так), но амортизированная стоимость - O (1). –
+1 для ваших усилий. Все еще путают с «амортизированной стоимостью». Можете ли вы сказать мне одну вещь, предположим, что Tree - сбалансированное двоичное дерево, и я делаю inorder и morris traversal. Могу ли я сказать, что худшая временная сложность - это O (N) и O (NlogN)? пожалуйста, направляйте меня на какую-либо ссылку для «амортизированной стоимости», если это возможно. – Trying