Morris算法介绍
Morris算法在遍历的时候避免使用了栈结构,而是让下层到上层有指针,具体是通过底层节点指向NULL的空闲指针返回上层的某个节点,从而完成下层到上层的移动。我们知道二叉树有很多空闲的指针,比如某个人节点没有右孩子,我们称这种情况为空闲状态,Morris算法的遍历就是利用了这些 空闲的指针!
Morris算法算法的规则:
当我拿到一个节点(node)的时候看它有没有左子树,没有的话向右指针方向移动
有的话找到左子树的最右节点,如果这个最右节点的右指针为空则让它指向node,然后node向左指针移动
,如果这个最右节点已经指向node,则让它指向空则让node向右指针移动
我们就拿一个普通的二叉树来说吧:
描述:我们从根节点开始,node节点就为1,1有左子树,找到1左子树的最右节点为5,5的右指针为空,让5的右指针指向node即1,然后node向左指针移动,变为2,2也有左子树,左子树的最右节点为4,4的右指针为空则指向2,node向左移动变为4,node为4没有左子树,所以node向右指针方向移动回到2(这是第二次来到2),2有左子树,并且它左子树的最右节点已经指向了node(即2),则让这个最右节点指向NULL,node向右指针移动来到5,5没有左子树,向右指针移动来到1,1有左子树,切左子树的最右节点指向了node(即自己),让最右节点指向NULL,node向右指针移动来到3,3有子树,左子树的最右节点右指针为空所以让他指向node(即3),node向左指针移动来到7,7没有左子树,向右指针移动回到3(第二次来到3),3有左子树切左子树的最右节点指向自己,则让左子树的最右节点指向NULL,node往右指针走,来到8,此树遍历完毕。
我们可以看到节点2,1,3在node走的过程中会两次来到它,而其他节点node只会来到一次!
归纳为:如果一个节点有左子树node就会访问它两次,如果没有左子树,node只会访问它一次。
这样我们就可以开始做前、中序遍历了:
前序遍历:
一个节点没有左子树直接打印当前节点
如果有的话(第一次来到此节点的时候就去打印),即再往左子树节点走之前打印
code
struct Node
{
int value;
Node* left;
Node* right;
Node(int data)
{
value = data;
}
};
//Morris前序遍历
void MorrisPre(Node* root)
{
if(root == NULL)
return;
No