一般方法遍历二叉树
一般方法遍历二叉树都是通过递归合着栈,递归本身存在函数调用栈,其空间复杂度必然是O(n);使用栈的情况下,由于遍历时需要将从当前节点到叶子节点之间的经过的所有节点压入栈中,所以最大需要O(h)的空间复杂度,h为树的高度。
图示Morris遍历
Morris遍历通过调整树的结构,可以只用O(1)的空间复杂度实现对二叉树的遍历。下图是Morris算法对二叉树遍历的完整的过程。
Morris中序遍历的流程
从图中的说明可以看出,Morris的最核心的思想就是:找到当前节点中序遍历的前驱结点,并将前驱节点的右节点指向当前节点,知道当前节点的左子树处理完成后,再将树结构调整回原状。
总结Morris中序遍历算法过程如下:
- 初始化当前节点指向根节点
- 如果当前节点不为空
- 如果当前节点没有左节点
- 输出当前节点的数据
- 设置当前节点指向当前节点的右节点
- 如果当前节点存在左节点
- 寻找当前节点的左子树的最右节点的右节点,设置其为前驱结点
- 如果前驱结点的右节点为空,则将其右节点指向当前节点(还未遍历过,需要修改树结构)
- 如果前驱节点的右节点已经指向当前节点,则将其右节点置空(已经遍历过,将树结构修改回原样)
- 设置当前节点指向当前节点的左节点
- 寻找当前节点的左子树的最右节点的右节点,设置其为前驱结点
- 如果当前节点没有左节点
Morris中序遍历的Java实现
1 | // Java program to print inorder traversal without recursion and stack |