二叉树的遍历通常有三种方法:
1.迭代
2.栈实现非迭代
3.Morris traversal实现非迭代
这三种方法的比较参照这篇中序遍历的题目。
Morris traversal利用了线索二叉树,将空间复杂度降为O(1),本篇继续探讨下它的其他遍历的实现。
线索二叉树
动机
1.在一个以链表形式存储的二叉树中,有n个节点,则有(n-1)个节点间指针,而节点结构体用于存储指针的则有2n个,造成了一定了浪费。
2.遍历树时费劲。
举个例子:
定义
节点中空的左指针指向其前驱节点,空的右指针指向后继节点。
举个例子:
问题又来了,如何判断指针指向的是子节点 还是 前驱/后继 呢?
于是结构体升级,增加了一个tag用于区别这两种情况。变成了:
举个例子:(tag为1表示前驱/后继,为0表示孩子)
Morris traversal中,就是利用了线索二叉树中记录后继节点的思想。
Morris Traversal
接下来,具体分析Morris traversal的实现
中序
这里再次阐述一遍中序的实现,与前面链接的例子有一处不同(在处理节点间指向关系上),目的是与其他顺序遍历尽量保持一致,方便比较。
算法步骤:
1.初始化当前节点curr为根节点root。
2.while(curr != NULL):
if(curr->left == NULL):