`

Morris traversal: traverse binary tree inorder with no recursion and O(1) space

 
阅读更多

参考:http://pthread.blog.163.com/blog/static/169308178201210112045787/

 

Most textbooks mention that binary tree can be traversed using recursion or , using stack without recursion. The recursive procedure is simple to write, and the stack version use extra space. 

There's also a very well designed algorithm that traverse a binary tree inorder without recursion and yet use only O(1) space -- Morris Traversal. In this traversal, we first create links to inorder successor and print the data using these links, and finally revert the changes to restore original tree.

 

1. Initialize current as root 
2. While current is not NULL
   If current does not have left child
      a) Print current’s data
      b) Go to the right, i.e., current = current->right
   Else
      a) Make current as right child of the rightmost node in current's left subtree
      b) Go to this left child, i.e., current = current->left
The algorithm is also very easy to implementation:

template<typename T>
void morris_traversal(bst_node_t<T>* root)
{
bst_node_t<T>* current = root;
while (current) {
if (!current->left) {
std::cout << current->data << " ";
current = current->right;
} else {
bst_node_t<T>* it = current->left;
while (it->right && it->right != current) {
it = it->right;
}
if (!it->right) {
it->right = current;
current = current->left;
} else {
std::cout << current->data << " ";
it->right = NULL;
current = current->right;
}
}
}
}

 
But however, this algorithm is not so easy to understand. Why every time we encounter a node that has both right child and left child, we have to set current node as right child of the right most node of the current's left subtree? How does this algorithm restore the tree after we temporarily change the tree structure?
 
Here we give some pictures to demonstrate this process:
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space - pthread - pthread的博客
 
 At the beginning, we start from the root node of the tree as current.
 
 
 
 
 
 
 
 
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space - pthread - pthread的博客
 
Second, we find that node 8(current) has both left and right child, so we set node 8 as right child of the right most node of the left subtree, that's node 7.
 

/*

    here current points to node 8,it to node 3
*/
bst_node_t<T>* it = current->left;
/*
    go to che right most child of node 3 that is node 7
*/
while (it->right && it->right != current) {
    it = it->right;
}
/*
    here it points to node 7, current to node 8
*/
if (!it->right) {
    /*
        set current(node 8) as right child of node 7, notice
        that node 8's left child pointer still points to node 3
     */
    it->right = current;
    /*
        current goes left, that is, current points to node 3
    */
    current = current->left;
}
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space - pthread - pthread的博客
 

Repeat the process above, with current node 3, go left child of current node, that is node 1. Then we find that node 1 has no right child. 

 
So we set node 3 as node 1's left right child and set current as node 1.Node 1 has no left child, so we goes into this piece of code, and set current as node 3
 

if (!current->left) {
std::cout << current->data << " ";
current = current->right;
}

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space - pthread - pthread的博客
As node 3 goes to its left most child and find itself, which means that we visit node 3 in the second time, so here we restore the tree by set node 1's right child to NULL, and visit node 3.
 
 

/*
current => node 3
it => node 1
*/
bst_node_t<T>* it = current->left;
/*
here we find that it->right = node 3 = current
so break the loop
*/
while (it->right && it->right != current) {
it = it->right;
}
if (!it->right) {
it->right = current;
current = current->left;
} else {
/*
we visit node 3 in the second time, thus print data
*/
std::cout << current->data << " ";
/*
adjust node 1's right child pointer to null as it originally be
*/
it->right = NULL;
/*
we complete traversal left child of node 3, current goes right, that is node 5
*/
current = current->right;
}

 

 

Here we have covered each condition of Morris Traversal. The loop continues and the whole tree will be traversed and restored.
分享到:
评论

相关推荐

    leetcodetreenode-morris-inorder-traversal:二叉树的莫里斯中序遍历

    binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List&lt; Integer &gt; inorderTraversal ( TreeNode ...

    Algorithms and Data Structures - Niklaus Wirth

    - **Tree Search and Insertion**: Searching and inserting nodes in a binary tree. - **Tree Deletion**: Removing nodes while maintaining tree structure. - **Analysis of Tree Search and Insertion**: ...

    莫里斯(Morris)::artist_palette:William Morris ggplot2的调色板:artist_palette:

    William Morris ggplot2调色板 克里斯蒂安·霍格德 介绍 该软件包为ggplot2提供了许多调色板,这些调色板的灵感来自英国纺织品设计师,诗人,小说家和活动 。 威廉·莫里斯(William Morris)(1834-1896)是英国...

    LeetCode最全代码

    401 | [Binary Watch](https://leetcode.com/problems/binary-watch/) | [C++](./C++/binary-watch.cpp) [Python](./Python/binary-watch.py) | _O(1)_ | _O(1)_ | Easy | | 411 | [Minimum Unique Word ...

    Mano, M. Morris and M.D. Ciletti; Digital Design, 2th edition

    Digital Design The goal of this course is to provide students with ... Major topics include: binary arithmetic, Boolean algebra, logic gate minimization, and combinational and sequential circuit design.

    Probability and Statistics (4th Edition) by Morris H. DeGroot

    《概率与统计》(第四版)是Morris H. DeGroot所著的一本经典教材,专注于统计学领域的深入学习。这本书以其清晰易懂的论述风格,为读者提供了丰富的统计学理论和应用知识。 首先,我们要理解概率与统计的基础概念...

    二叉树的Morris遍历

    二叉树的Morris遍历是一种高效的遍历算法,它不需要使用额外的空间来存储节点的父节点或子节点,仅利用了二叉树本身的结构。这种方法由C. L. Morris在1970年提出,主要用于提升二叉树遍历的效率。在二叉树的三种基本...

    Morris.Js 漂亮的时序线型图

    **Morris.js 漂亮的时序线型图** Morris.js 是一个基于 JavaScript 的数据可视化库,专为创建美观、高效的时序线型图而设计。它使用了著名的 Raphaël.js 作为底层图形渲染引擎,使得在各种浏览器上都能得到良好的...

    完整版Solution Manual)Probability and Statistics,4th Edition by Morris H. Degroot.

    亲测好用,挺不错的资源,大家快来下载吧!挺有用的!需要的话可以来下载哦!网上大部分后面没有答案,这个是很全的 ...(Solution Manual)Probability and Statistics,4th Edition by Morris H. Degroot

    算法导论--Introduction.to.Algorithms

    the second half then engages more advanced readers and curious students with compelling material on both the possibilities and the challenges in this fascinating field." —Shang-Hua Teng, University ...

    vue-morris:VueJS组件包装Morris.js

    维莫里斯Vue.js组件包装了Morris.js库有关文档,请参见 取决于Vue.js v2.1.0 +安装使用npm npm install vue-morris --save 不要忘记在package.json声明jQuery,如果您使用的是Webpack,则应该在webpack.config.js...

    数据结构常用算法c++实现

    Binary search tree Dynamic order statistics Red-black tree Interval tree Prefix Tree(Trie) *Suffix Tree(未实现)* B-Tree Hash by multiplication Hash table Universal hash function Perfect hash Java's ...

    morris.js-master.zip

    1. **Morris.js简介** Morris.js是由Oliver Night开发的一款轻量级的图表库,它依赖于另一款流行的JavaScript库—— Raphael.js,用于在SVG或VML中绘制图形。由于这两个库的结合,Morris.js能够在所有现代浏览器...

    Morris蠕虫源代码

    1. **利用漏洞**:Morris蠕虫利用了三个主要的漏洞:(1) rsh命令的认证绕过,允许蠕虫远程执行代码;(2) finger服务的漏洞,蠕虫可以通过它获取主机信息并可能执行代码;(3) sendmail程序的漏洞,蠕虫可以通过邮件...

    前端项目-angular-morris.zip

    Angular-Morris 是一个专门为 AngularJS(一种由Google维护的前端JavaScript框架)设计的库,它使得在Angular应用中集成Morris.js图表变得更加简单和直观。Morris.js是一款优秀的图表库,用于创建各种类型的数据可视...

    二叉树遍历问题-二叉树遍历问题

    2. **中序遍历**(Inorder Traversal): - 中序遍历在二叉搜索树(BST)中特别重要,因为它能按照升序或降序输出节点值。遍历顺序是:先遍历左子树,然后访问根节点,最后遍历右子树。伪代码:`Inorder(left) -&gt; ...

    二叉树的遍历.docx

    2. **中序遍历**(Inorder Traversal): - 访问顺序:左子树 -&gt; 根节点 -&gt; 右子树 - 中序遍历的顺序是先访问左子树,然后访问根节点,最后访问右子树。在二叉搜索树中,中序遍历的结果会得到排序后的节点值序列,...

    Morris_Lecar_Matlab.zip_MORRIS LECAR_Morris Lecar model_Morris a

    《Morris-Lecar模型在Matlab环境中的实现与应用》 Morris-Lecar模型是一种经典的神经元动力学模型,由John H. Morris和Vivian Lecar于1981年提出,用于描述神经元的电压门控离子通道行为。这个模型通过简化复杂的...

    Morris, J. 心理学与教学:人文主义观点。 纽约:兰登书屋,1978 年,494 页,[美元]13.95

    Morris, J. Psychology and Teaching: A Humanistic View. New York: Random House, 1978, 494 pp., [dollar]13.95 Psychology in the Schools 1981. / 8 , 121-127 B O O K R E V I E W S GILBERT R. GREDLER...

Global site tag (gtag.js) - Google Analytics